Data structure---discrete storage (linked list)

Discrete storage (linked list)

Linked list definition:

(1) n nodes are distributed discretely ;
(2) connected by pointers ;
(3) each node has only one predecessor node , and each node has only one subsequent node ;
(4) the first node has no predecessor node , and the tail node has no subsequent node .

Terminology:

  • First node : the first valid node
  • End node : the last valid node
  • Head node :
    The data type of the head node is the same as that of the first node.
    The node before the first valid node. The head node does not store valid data. The purpose of adding the head node is to facilitate the operation of the linked list.
  • Head pointer : pointer variable pointing to the head node
  • Tail pointer : Pointer to the tail node

Determining a linked list requires several parameters (or if a function is expected to operate on the linked list we need to receive at least those information of the linked list):
only one parameter is needed: the head pointer, because we can deduce all the information of the linked list through it.

classification

(1) Single-linked list
(2) Double-linked list: each node has two pointer fields
(3) Circular linked list: All other nodes can be found through any node
(4) Non-cyclic linked list

algorithm:

  • Traverse
  • Find
  • Empty
  • destroy
  • Find the length
  • Sort
  • Delete node
r = p->pNext;
p->pNext = r->pNext;
free(r);
  • Insert node
    insertion example
    Insert picture description here
    Insert q node behind p node
    Method 1: First temporarily define a pointer r pointing to the node behind p
r = p->pnext;
p->pNext = q;
q->pNext = r;

Method 2: Insert the node pointed to by q behind the node pointed to by p

q->pNext = p->pNext;
p->pNext = q;

Algorithm : The narrowly defined algorithm is closely related to the way the data is stored, and the generalized algorithm has nothing to do with the way the data is stored.
Generic : (give you an illusion, but the awesome guys have made it right from the inside)
achieved by some technology The effect is: different storage methods perform the same operations

The real learning method of algorithms: You have solved many algorithms at all! ! ! ! ! ! Because many things belong to mathematics, so we find out the answer if we can understand it, but most people can't understand it. There are three steps, according to the process, the sentence, and the number of trials. This process will definitely make mistakes constantly, so keep making mistakes and correcting mistakes. Only by repeatedly typing many times can there be improvement. If you really don’t understand, I’ll recite it first.

The advantages and disadvantages of linked lists:

  • Advantages:
    (1) No space limitation
    (2) Insert and delete elements quickly
  • Disadvantages:
    (1) The access speed is very slow.

Single linked list implementation code (c language implementation)

#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>

typedef enum __bool {
    
     false = 0, true = 1, } bool;

typedef struct Node
{
    
    
    int data;  //数据域
    struct Node * pNext;  //指针域
}NODE,*PNODE;

//函数声明
PNODE create_list(void);
void traverse_list(PNODE pHead);
bool is_empty(PNODE pHead);   //判断是否为空
int length_list(PNODE pHead);     //链表长度
bool insert_list(PNODE pHead,int pos,int val);   //插入
bool delete_list(PNODE pHead,int pos,int * pval);    //删除
void sort_list(PNODE pHead);   //排序

//创建链表
PNODE create_list(void)
{
    
    
    int i;
    int len;
    int val;   //输入临时存储的值

    //分配了一个不存放有效数据的头结点
    PNODE pHead = (PNODE)malloc(sizeof(NODE));
    if(NULL ==  pHead)
    {
    
    
        printf("内存分配失败\n");
        exit(-1);
    }
    PNODE pTail = pHead;
    pTail->pNext = NULL;

    printf("请输入你要生成节点的个数,len = ");
    scanf("%d",&len);

    for(i = 0; i < len; ++i)
    {
    
    
        printf("请输入第%d个节点的值.",i+1);
        scanf("%d",&val);

        PNODE pNew = (PNODE)malloc(sizeof(NODE));
        if(NULL ==  pNew)
        {
    
    
            printf("内存分配失败\n");
            exit(-1);
        }

        pNew->data = val;

        pTail->pNext = pNew;
        pNew->pNext = NULL;
        pTail = pNew;
    }

    return pHead;
}

//遍历链表
void traverse_list(PNODE pHead)
{
    
    
    PNODE p = pHead->pNext;

    while(NULL != p)
    {
    
    
        printf("data in list is %d \n",p->data);
        p = p->pNext;
    }
    //printf("\n");
}

//判断是否为空
bool is_empty(PNODE pHead)
{
    
    
    if(NULL == pHead->pNext)
        return true;
    else
        return false;
}

//链表长度
int length_list(PNODE pHead)
{
    
    
    PNODE p = pHead->pNext;

    int count = 0;

    while(NULL != p)
    {
    
    
        ++count;
        p = p->pNext;
    }

    return count;
}

//排序
void sort_list(PNODE pHead)
{
    
    
    int i,j,t;
    int len = length_list(pHead);
    PNODE p,q;

    for(i = 0,p = pHead->pNext; i < len-1; ++i,p = p->pNext)
    {
    
    
        for(j = i+1,q = p->pNext; j < len; ++j,q = q->pNext)
        {
    
    
            if(p->data > q->data)
            {
    
    
                t = p->data;
                p->data = q->data;
                q->data = t;
            }
        }
    }
}

//在PHead所指向链表的第pos个节点的前面插入一个新的节点,该节点的值是val
//并且。pos值从1开始
bool insert_list(PNODE pHead,int pos,int val)
{
    
    
    int i = 0;
    PNODE p = pHead;

    while(NULL != p && i < pos-1)
    {
    
    
        p = p->pNext;
        ++i;
    }

    if(i > pos-1 || NULL == p)
        return false;

    PNODE pNew = (PNODE)malloc(sizeof(NODE));
    if(NULL == pNew)
    {
    
    
        printf("动态分配内存失败\n");
        exit(-1);
    }

    pNew->data = val;

    PNODE q = p->pNext;
    p->pNext = pNew;
    pNew->pNext = q;

    return true;
}
//删除节点
bool delete_list(PNODE pHead,int pos,int * pval)
{
    
    
    int i = 0;
    PNODE p = pHead;

    while(NULL != p->pNext && i < pos-1)
    {
    
    
        p = p->pNext;
        ++i;
    }

    if(i > pos-1 || NULL == p->pNext)
        return false;

    PNODE q = p->pNext;
    *pval = q->data;

    //删除p节点后面的节点
    p->pNext = p->pNext->pNext;
    free(q);
    q = NULL;

    return true;
}

int main()
{
    
    
    int len;
    int val;
    PNODE pHead = NULL;

    pHead = create_list(); // 创建一个非循环单链表
    printf("********普通遍历输出测试*********\n");
    traverse_list(pHead);

    if(is_empty(pHead))   //为空测试
        printf("链表为空\n");
    else
         printf("链表不为空\n");

    len = length_list(pHead);   //长度测试
    printf("链表长度为:%d\n",len);

    sort_list(pHead);  //排序测试
    printf("********排序测试*********\n");
    traverse_list(pHead);



    //插入节点测试
    insert_list(pHead,3,50);
    printf("********插入节点测试*********\n");
    traverse_list(pHead);

    //删除节点测试
    printf("*********删除节点测试*********\n");
    if(delete_list(pHead,3,&val))
    {
    
    
        traverse_list(pHead);
        printf("删除成功,删除的节点中数据域 data 值为:%d\n",val);
    }
    else
    {
    
    
        printf("删除失败,删除的节点不存在\n");
    }

    return 0;
}

Guess you like

Origin blog.csdn.net/qq_41782149/article/details/91385596