Addition, deletion, modification, query and sorting issues of one-way linked list and doubly linked list


This article introduces the addition, deletion, modification and sorting of linked lists, the most important of which is the use of pointers!

singly linked list

Define a one-way linked list, which contains an integer data and a pointer pointing backward.

typedef struct linklist{
    
    
    int data;
    struct linklist *next;
}LinkList;

The pointer is responsible for pointing to the next correct linked list element every time the linked list changes. When it is at the end of the linked list, it points to NULL.
Create a linked list through user input, and finally the function that creates the linked list returns the head pointer of the linked list.

LinkList *CreateLinkList()
{
    
    
    int n = 0;
    LinkList *head,*p,*q;
    head = NULL;
    p = q = (LinkList *)malloc(sizeof(LinkList));
    printf("input data %d (input 65535 end):",n+1);
    scanf("%d",&p->data);
    if(p->data == 65535)
        return head;
    
    while(1)
    {
    
    
        n++;
        if(n==1)
            head = p;
        else
            q->next = p;
        q = p;
        p = (LinkList *)malloc(sizeof(LinkList));
        printf("input data %d (input 65535 end):",n+1);
        scanf("%d",&p->data);
        if(p->data == 65535)
            break;
    }
    q->next = NULL;
    return head;
}

The creation of the linked list is completed through user input, so the memory is dynamically allocated. Each time one is used, one is allocated. Remember to point the tail pointer to NULL at the end.
The function to print the linked list is as follows.

void print_linklist(LinkList *head)
{
    
    
    LinkList *p;
    p = head;
    if(head != NULL)
    {
    
    
        do{
    
    
            printf("%d ",p->data);
            p = p->next;
        }while(p != NULL);
    }
    else
    {
    
    
        printf("The link list is empty!\n");
    }
}

Printing a linked list is relatively simple. The premise is to ensure that the tail pointer of the linked list points to NULL, otherwise it will fall into an endless loop!
The bubble sort function is as follows.

void bubblesort(LinkList *head)
{
    
    
    LinkList *cur,*tail;
    cur = head;
    tail = NULL;
    while(cur != tail)
    {
    
    
        while(cur->next != tail)
        {
    
    
            if(cur->data < cur->next->data)
            {
    
    
                int temp;
                temp = cur->data;
                cur->data = cur->next->data;
                cur->next->data = temp;
            }
            cur = cur->next;
        }
        tail = cur;
        cur = head;
    }
}

Bubble sorting is to move the maximum or minimum value in the sequence to the leftmost or rightmost value of the linked list each time. In this way, after several sortings, the linked list sequence is arranged from small to large or from large to small.
The selection sort function is as follows.

void selectsort(LinkList *head)  //选择排序
{
    
    
    LinkList *cur,*p,*q;
    int cur_data,min_data;
    cur = head;
    p = q = NULL;
    while(cur != NULL)
    {
    
    
        p = cur->next;
        cur_data = cur->data;
        min_data = cur_data;
        while(p != NULL)
        {
    
    
            if(p->data < min_data)
            {
    
    
                min_data = p->data;
                q = p;
            }
            p = p->next;
        }
        if(cur_data != min_data)
        {
    
    
            cur->data = min_data;
            q->data = cur_data;
        }
        cur = cur->next;
    }
}

Selection sorting is to find the maximum or minimum value in the sequence in a sort, then remember the position, and exchange the values ​​of the current pointer position and the record position after each check to achieve the purpose of sorting.
Insert in linked list.

LinkList *linklist_insert(LinkList *head,int data)
{
    
    
    LinkList *p,*q;
    q = (LinkList *) malloc(sizeof(LinkList));
    q->data = data;
    
    if(head == NULL || data <= head->data)  //在链头插入
    {
    
    
        q->next = head;
        head = q;
    }
    else
    {
    
    
        p = head;
        while(p != NULL)
        {
    
    
            if(data >= p->data && (p->next == NULL || data <= p->next->data))
            {
    
    
                q->next = p->next;
                p->next = q;
                break;
            }
            p = p->next;
        }
    }
    return head;
}

The insertion operation in this code is performed after sorting the values ​​​​of the linked list from small to large. After inserting the value, the order of the sequence remains unchanged, so it is necessary to find a suitable insertion position.
delete in the linked list.

LinkList *linklist_delete(LinkList *head,int data)
{
    
    
    LinkList *p,*q;
    p = head;
	if(head == NULL)
	{
    
    
		return NULL;
	}
    while(p != NULL)
    {
    
    
        if(p->data != data)
            p = p->next;
		else
			break;
   }
	if(p == NULL)   //要删除的数不在链表中
    {
    
    
       printf("not found %d in the link list\n",data); 
       return head;
	}
	else
	{
    
    
		p = head;
	}
    while(p != NULL)
    {
    
    
        if(p->data == data) //链头就是要删除的
        {
    
    
            q = head;
            head = p->next;
            p = head;
            free(q);
        }
        else if(p->data < data && p->next->data == data)
        {
    
    
            q = p->next;
            p->next = q->next;
            free(q);
            if(p->next == NULL)
                break;
        }
        else   //如果找到了要删除的,指针不动,从当前位置接着判断
        {
    
    
            p = p->next;
        }
    }
    return head;
}

When deleting in a linked list, first check whether the value to be deleted is in the linked list. If it is, perform the deletion operation. The deletion operation will delete all the values ​​in the linked list that are equal to the value to be deleted. If not, the user will be prompted to enter a value that is not in the linked list. in the linked list.
Modify a value in the linked list.

LinkList *linklist_modify(LinkList *head,int data,int modify_value)
{
    
    
    LinkList *p;
    p = head;
    if(head == NULL)
	{
    
    
		return NULL;
	}
    while(p != NULL)
    {
    
    
        if(p->data != data)
            p = p->next;
		else
			break;
   }
	if(p == NULL)
    {
    
    
       printf("not found %d in the link list\n",data); 
       return head;
	}
	else
	{
    
    
		p = head;
	}
    while(p != NULL)
    {
    
    
        if(p->data == data)
        {
    
    
            p->data = modify_value;
        }
        p = p->next;
    }
    return head;
}

When modifying the value in the linked list, you must first query to see if the value to be modified is in the linked list. If it is, replace it with the value to be replaced. Otherwise, a message will be printed to prompt the user that the value to be modified is not in the linked list.


Doubly linked list

A doubly linked list is similar to a one-way linked list, but there is an extra pointer, which not only points to the backward direction, but also points to the forward direction. Be sure to pay attention to the forward and backward pointing when the current node is NULL, although no error will be reported. , but the result may not be as expected.
Define a double linked list, which contains an integer data and two pointers, pointing to the forward and backward directions respectively.

typedef struct linklist{
    
    
    int data;
    struct linklist *pre;
    struct linklist *next;
}LinkList;

The creation of a doubly linked list is similar to that of a one-way linked list, but pay attention to the pointing of the pre pointer.

LinkList *CreateLinkList()
{
    
    
    int n = 0;
    LinkList *head,*p,*q;
    head = NULL;
    p = q = (LinkList *)malloc(sizeof(LinkList));
    printf("input data %d (input 65535 end):",n+1);
    scanf("%d",&p->data);
    if(p->data == 65535)
        return head;
    
    while(1)
    {
    
    
        n++;
        if(n==1)
        {
    
    
            head = p;
            head->pre = NULL;
        }    
        else
        {
    
    
            p->pre = q;
            q->next = p;
        } 
        q = p;
        p->next = NULL;
        p = (LinkList *)malloc(sizeof(LinkList));
        printf("input data %d (input 65535 end):",n+1);
        scanf("%d",&p->data);
        if(p->data == 65535)
            break;
    }
    return head;
}

The insertion code of the doubly linked list is as follows. It should be noted that only when the backward direction of the insertion position is not empty, the pre pointer can be used in the backward direction.

LinkList *linklist_insert(LinkList *head,int data)
{
    
    
    LinkList *p,*q;
    q = (LinkList *) malloc(sizeof(LinkList));
    q->data = data;
    
    if(head == NULL || data <= head->data)  //在链头插入
    {
    
    
        q->next = head;
        if(head != NULL)
            head->pre = q;
        q->pre = NULL;
        head = q;
    }
    else
    {
    
    
        p = head;
        while(p != NULL)
        {
    
    
            if(p->data <= data && (p->next == NULL || p->next->data >= data))
            {
    
    
                q->next = p->next;
                q->pre = p;
                if(p->next != NULL)
                    p->next->pre = q;
                p->next = q;
                break;
            }
            p = p->next;
        }
    }
    return head;
}

The following is the code to delete one or some nodes in the doubly linked list. Please pay attention to exit the loop in time when the pointer points to NULL.

LinkList *linklist_delete(LinkList *head,int data)
{
    
    
    LinkList *p,*q;
    p = head;
	if(head == NULL)
	{
    
    
		return NULL;
	}
    while(p != NULL)
    {
    
    
        if(p->data != data)
            p = p->next;
		else
			break;
   }
	if(p == NULL)
    {
    
    
       printf("not found %d in the link list\n",data); 
       return head;
	}
	else
	{
    
    
		p = head;
	}
   
    /*
    while(p != NULL)
    {
        if(p->data == data) //链头就是要删除的
        {
            q = head;
            head = p->next;
            if(p->next != NULL)
                p->next->pre = head;
            else
                break;
            head->pre = NULL;   //head非空时,其pre才可以指向NULL
            p = head;
            free(q);
        }
        else if(p->data < data && p->next->data == data)
        {
            q = p->next;
            p->next = q->next;
            if(p->next != NULL)
                q->next->pre = p;
            free(q);
            if(p->next == NULL)
                break;
        }
        else
        {
            p = p->next;
        }
    }
    */

    while(p != NULL)
    {
    
    
        if(p->data == data)
        {
    
    
            if(p->pre == NULL)           //链头就是要删除的
            {
    
    
                q = head;
                p = p->next;
                if(p != NULL)
                {
    
    
                	p->pre = NULL;    //一定要确保当前节点非空,pre才可以指向NULL
                	head = p;
                }    
                else
                {
    
    
                    head = NULL;
                    free(q);
                    break;
                } 
            }
            else
            {
    
    
                q = p;
                p->pre->next = p->next;
                if(p->next != NULL)
                {
    
    
					p->next->pre = p->pre;
					p = p->next; 
				}
                else
                {
    
    
                    free(q);
                    break;
                } 
            }
            free(q);
        }
        else
        {
    
    
            p = p->next;
        }
    }
    return head;
}

Modifications in a doubly linked list are the same as modifications in a one-way linked list.


operation result

The operation results of one-way linked list and doubly linked list are the same, and the results are shown in the figure below.
Insert image description here
The deletion and modification operations in this code do not delete or modify one of the linked lists. All the ones with the same value will be deleted or modified, as shown in the figure below.
Insert image description here


Complete code

Complete code for one-way linked list and doubly linked list

Guess you like

Origin blog.csdn.net/weixin_42570192/article/details/132624884