首页 > 编程语言 >代码随想录算法训练营第三天| LeetCode 203.移除链表元素(同时也对整个单链表进行增删改查操作) 707.设计链表 206.反转链表

代码随想录算法训练营第三天| LeetCode 203.移除链表元素(同时也对整个单链表进行增删改查操作) 707.设计链表 206.反转链表

时间:2023-07-28 21:34:18浏览次数:50  
标签:结点 LNode int 随想录 next 链表 移除 NULL 节点

203.移除链表元素 

        题目链接/文章讲解/视频讲解::https://programmercarl.com/0203.%E7%A7%BB%E9%99%A4%E9%93%BE%E8%A1%A8%E5%85%83%E7%B4%A0.html

       卡哥题目建议:本题最关键是要理解虚拟头结点的使用技巧,这个对链表题目很重要。

      做题思路: 

      1,分为不带头节点的和带(虚拟)头节点的两种情况。

      1.1 . 不带头节点就是直接在原链表上删除节点,删第1个节点之后的节点需要改一下指针指向,就是用文字描述,比如删第2个节点,让第1个节点的指向第3个节点,再释放第2个节点。同理,除了第1个有效节点即首节点外,其他节点都是通过前一个节点来删除当前节点,但是首节点没有前1个节点。所以首节点如何删除呢,其实只要将首节点的指针指向,向后移动一位就可以,这样就从链表中删除了一个首节点。

     1.2. 带虚拟头节点就是在初始化链表的时候,创建出一个头节点,方便使原链表的所有节点就都可以按照统一的方式进行删除了。因为看 3.1 的思路,需要单独写一段逻辑来处理移除头结点的情况。

      在后续代码中 ,使用LinkList,强调这是一个单链表; 使用LNode,强调这是一个节点。

      这里的代码模仿了我写的博客:https://www.cnblogs.com/romantichuaner/p/17557080.html,我用C语言写的。根据这个题,作了删除函数的改变。

 

 1 bool DeleteList(LinkList &L, int val)//删除表L中值为 val 的元素 
 2 {
 3     LNode *p = L->next, *q = L, *s; //L是头节点,L->next是第一个有效节点 
 4   
 5     while(p != NULL) //从第一个有效节点开始循环找值为val的节点 
 6     {
 7         if(p->data == val)
 8         {//原本顺序 p,q,s 
 9             s = p;  //找到要删除的节点的话,就先用节点s保存p , 
10             p = p->next;//更改p的指向,在删除思路里说过,现在顺序 s,q,p
11             q->next = p;//q的指向也要记得改 
12             free(s); //释放原来p所在的节点,只不过现在变成了s 
13         }
14         else
15         { 
16             q = p;//没有找到的话,就依次遍历其他节点,有种交换的感觉 
17             p = p->next;
18         }
19     }
20     return true;
21 }

        完整代码的函数调用也改变了。

1 case 2: //2,删除数据
2             int val;
3             scanf("%d",&val);
4             DeleteList(L,val);
5             getchar();
6             break;

 

     本题中是把链表中的元素键盘输入的,所以这里我还改了添加函数的调用。

 1 case 1: //1,添加数据
 2             printf("请输入元素个数:\n");
 3             scanf("%d",&n);
 4             printf("请添加元素:\n");
 5             for(int i = 1; i <= n; i++)
 6             {
 7                 scanf("%d",&num);
 8                 InsertList(L,i,num);
 9             } 
10             printf("数据添加成功!\n");
11             getchar();
12             break; 

     综上,本题完整代码以及拓展的一些操作代码如下:

  1 #include <stdio.h>
  2 #include <malloc.h>
  3 typedef struct LNode{ //定义单链表结点类型    //这种方式代码可读性更强
  4     int data;//每个节点存放一个数据元素
  5     struct LNode *next;//指针指向下一个节点
  6 }LNode, *LinkList; //LNode 是struct LNode 的别名,LinkList是struct LNode *的别名,指针指向整个结构体
  7 bool InitList(LinkList &L) //初始化一个单链表(带头结点)
  8 {
  9     L = (LNode *)malloc(sizeof(LNode)); //分配一个头节点,malloc函数强调返回是一个节点(LNode *),如果单链表有头节点,则头指针指向头节点,即 LinkList L = (LNode *)malloc(sizeof(LNode)); 等号有指向作用
 10     if(L == NULL) //内存不足,分配失败,就没有创建出单链表,因为已经分配了一个节点,所以只能内存不足的原因,空表是没有节点
 11         return false;
 12     L->next = NULL;//目前只有一个头节点,头节点之后暂时还没有节点
 13     return true;
 14 }
 15 bool InsertList(LinkList &L, int i, int e) //在第 i 个位置插入元素 e (带头结点)
 16 {
 17     if(i < 1) //只能在头结点之后插入,头结点是第0个,之后是第1个
 18         return false;
 19     LNode *p; //LNode * 强调这是一个结点,声明一个结点,表示指针p指向当前找到的结点
 20     p = L; //L是指向头结点的头指针,再把刚开始的指针p指向L,表示目前的指针p指向头结点
 21     int j = 0;//记录当前p指向的是第几个结点,从头结点0开始
 22     while(p!= NULL && j < i - 1) //循环找到第 i-1 个结点,j = i-1,不进入循环,内存满了,不进入循环
 23     {
 24         p = p->next; //p指向下一个结点
 25         j++;
 26     }
 27     if(p==NULL) //i值不合法,如果有4个结点,那i不能等于6,因为 p = p->next,在第5个位置之后满了,p指向NULL,下一步p->next出错了,根本找不到表的某个位置
 28         return false;
 29     LNode *s = (LNode *)malloc(sizeof(LNode));//创建一个节点,这个节点的数据域就是e
 30     s->data = e;
 31     s->next = p->next;  //自己画图理解,一开始p后的节点不是s,这里让p的下一个节点变成了在s的下一个节点
 32     p->next = s; //将结点s连到p之后
 33     return true; //插入成功
 34 }
 35 void ShowList(LinkList L) //显示
 36 {
 37     if(L->next == NULL)
 38        printf("这是一个空表\n");
 39     while(L != NULL)
 40     {
 41         L = L->next;
 42         printf("%d ",L->data);
 43     }
 44 
 45 }
 46 bool DeleteList(LinkList &L, int val)//删除表L中值为 val 的元素 
 47 {
 48     LNode *p = L->next, *q = L, *s; //L是头节点,L->next是第一个有效节点 
 49   
 50     while(p != NULL) //从第一个有效节点开始循环找值为val的节点 
 51     {
 52         if(p->data == val)
 53         {//原本顺序 p,q,s 
 54             s = p;  //找到要删除的节点的话,就先用节点s保存p , 
 55             p = p->next;//更改p的指向,在删除思路里说过,现在顺序 s,q,p
 56             q->next = p;//q的指向也要记得改 
 57             free(s); //释放原来p所在的节点,只不过现在变成了s 
 58         }
 59         else
 60         { 
 61             q = p;//没有找到的话,就依次遍历其他节点,有种交换的感觉 
 62             p = p->next;
 63         }
 64     }
 65     return true;
 66 }
 67 int GetList(LinkList &L, int i)//按位查找,返回第 i 个元素(带头节点)
 68 {
 69     if(i < 0)//有头节点,头节点是第0个节点,所以查找元素i不能小于0
 70         return 0;
 71     LNode *p;
 72     int j = 0;
 73     p = L;
 74     while(p != NULL && j < i) //找的是第i个节点,插入那里找的是第i-1 个节点
 75     {  //如果i大于表的长度,那循环找到的p会指向NULL,不会进入循环体,最后返回NULL
 76         p = p->next;
 77         j++;
 78     }
 79     return p->data;
 80 } //平均时间复杂度为O(n)
 81 int UpdateList(LinkList &L, int i, int num)
 82 {
 83    if(i < 0)//有头节点,头节点是第0个节点,所以查找元素i不能小于0
 84         return 0;
 85     LNode *p;
 86     int j = 0;
 87     p = L;
 88     while(p != NULL && j < i) //找的是第i个节点,插入那里找的是第i-1 个节点
 89     {  //如果i大于表的长度,那循环找到的p会指向NULL,不会进入循环体,最后返回NULL
 90         p = p->next;
 91         j++;
 92     }
 93     p->data = num;
 94     return p->data;
 95 }
 96 void Destroy(LinkList &L) //销毁单链表
 97 {
 98     LNode *p;
 99     while(L != NULL)
100     {
101         p = L;
102         L = L->next;
103         free(p);
104     }
105 }
106 void ShowMenu()
107 {
108     printf("************************\n");
109     printf("*****  1,添加数据  *****\n");
110     printf("*****  2,删除数据  *****\n");
111     printf("*****  3,查找数据  *****\n");
112     printf("*****  4,修改数据  *****\n");
113     printf("*****  5,显示数据  *****\n");
114     printf("*****  0,销毁并退出  ***\n");
115 }
116 int main()
117 {
118     LinkList L;//声明一个单链表
119     InitList(L);//初始化函数调用
120     int n = 0;
121     int num = 0;
122     int select = 0; //创建选择输入的变量
123     while (true)
124     {
125         //菜单调用
126         ShowMenu();
127         printf("请输入你的选择\n");
128         scanf("%d", &select);
129         switch (select)
130         {
131         case 1: //1,添加数据
132             printf("请输入元素个数:\n");
133             scanf("%d",&n);
134             printf("请添加元素:\n");
135             for(int i = 1; i <= n; i++)
136             {
137                 scanf("%d",&num);
138                 InsertList(L,i,num);
139             } 
140             printf("数据添加成功!\n");
141             getchar();
142             break;
143         case 2: //2,删除数据
144             int val;
145             scanf("%d",&val);
146             DeleteList(L,val);
147             getchar();
148             break;
149         case 3: //3,查找数据
150             printf("查找的元素是:%d\n",GetList(L,1));
151             getchar();
152             break;
153         case 4: //4,修改数据
154             UpdateList(L,1,0);
155             printf("修改成功!\n");
156             getchar();
157             break;
158         case 5: //4,显示数据
159             printf("单链表的数据有:");
160             ShowList(L);
161             getchar();
162             break;
163         case 0: //0,退出
164             Destroy(L);
165             printf("单链表已销毁!");
166             printf("欢迎下次使用");
167             return 0;
168             break;
169 
170         default:
171             break;
172         }
173     }
174     return 0;
175 }

运行结果显示:

 

707.设计链表

         题目链接/文章讲解/视频讲解:https://programmercarl.com/0707.%E8%AE%BE%E8%AE%A1%E9%93%BE%E8%A1%A8.html

      卡哥题目建议: 这是一道考察 链表综合操作的题目,不算容易,可以练一练 使用虚拟头结点

       做题思路:

        1,先看 题目中的 get(index):获取链表中第 index 个节点的值。如果索引无效,则返回-1。我们需要找到前 index - 1 个节点。函数名自己一改就行。

 1 int GetList(LinkList &L, int i)//按位查找,返回第 i 个元素(带头节点)
 2 {
 3     if(i < 0)//有头节点,头节点是第0个节点,所以查找元素i不能小于0
 4         return -1;
 5     LNode *p;
 6     int j = 0;
 7     p = L;
 8     while(p != NULL && j < i) //找的是第i个节点,插入那里找的是第i-1 个节点
 9     {  //如果i大于表的长度,那循环找到的p会指向NULL,不会进入循环体,最后返回NULL
10         p = p->next;
11         j++;
12     }
13     return p->data;
14 } //平均时间复杂度为O(n)

        函数调用。 

1 case 3: //3,查找数据
2             printf("查找的元素是:%d\n",GetList(L,1));
3             getchar();
4             break;

 

      运行结果显示:

        2,addAtHead(val):在链表的第一个元素之前添加一个值为 val 的节点。插入后,新节点将成为链表的第一个节点。这个和头插法是一样的,看b站的视频吧

 1 bool List_HeadInsert(LinkList &L)//逆向建立单链表
 2 {
 3     LNode *s;
 4     int x;
 5     L = (LNode *)malloc(sizeof(LNode)); //创建头结点
 6     L->next = NULL; //初始为空链表,养成好习惯,只要是初始化单链表,都先把头指针指向NULL
 7     scanf("%d",&x);
 8     while(x != 9999)
 9     {
10         s = (LNode *)malloc(sizeof(LNode));    //第10行到第13行代码和后插操作InsertNextNode函数第5行到第10行代码是等同的
11         s->data = x;
12         s->next = L->next;//把新结点插入到头结点之后
13         L->next = s;//更改头指针指向
14         scanf("%d",&x);
15     }
16     return true;
17 }

       函数调用。注意要把主函数的初始化函数注释了,因为头插法和尾插法函数里就有初始化的一部分。

1 case 6: //头插法 
2             List_HeadInsert(L); 
3             getchar();
4             break;

 

      运行结果显示:

       3,addAtTail(val):将值为 val 的节点追加到链表的最后一个元素。这个和尾插法是一样的。

 1 LinkList List_TailInsert(LinkList &L) //正向建立单链表
 2 {
 3     int x; //插入的元素
 4     L = (LinkList)malloc(sizeof(LNode));//建立头结点
 5     LNode *s, *r = L; //声明结点,s是把插入的元素放在结点s,r为表尾指针,让s,r初始化指向,头结点
 6      L->next = NULL; //初始为空链表
 7     scanf("%d",&x);
 8     while(x != 9999) //输入9999表示结束,任意的一个数字
 9     {
10         s = (LNode *)malloc(sizeof(LNode)); //分配插入的结点
11         s->data = x;
12         r->next = s; //在r结点之后插入元素x
13         r = s; //永远保持r指向最后一个结点
14         scanf("%d",&x);
15      }
16     r->next = NULL; //插入数字完后,再把尾结点指针置空
17     return L; //返回链表L
18 } //时间复杂度为O(n)
         函数调用。
1 case 7: //尾插法
2             List_TailInsert(L);
3             getchar();
4             break;

 

      运行结果显示:

    4,addAtIndex(index,val):在链表中的第 index 个节点之前添加值为 val  的节点。如果 index 等于链表的长度,则该节点将附加到链表的末尾。如果 index 大于链表长度,则不会插入节点。如果index小于0,则在头部插入节点。模仿插入函数。  

 1 bool InsertList(LinkList &L, int i, int e) //在第 i 个位置插入元素 e (带头结点)
 2 {
 3     if(i < 1) //只能在头结点之后插入,头结点是第0个,之后是第1个
 4     {
 5         List_HeadInsert(L); //头插法 
 6     }
 7     
 8     LNode *p; //LNode * 强调这是一个结点,声明一个结点,表示指针p指向当前找到的结点
 9     p = L; //L是指向头结点的头指针,再把刚开始的指针p指向L,表示目前的指针p指向头结点
10     int j = 0;//记录当前p指向的是第几个结点,从头结点0开始
11     while(p!= NULL && j < i - 1) //循环找到第 i-1 个结点,j = i-1,不进入循环,内存满了,不进入循环
12     {
13         p = p->next; //p指向下一个结点
14         j++;
15     }
16     if(p==NULL) //i值不合法,如果有4个结点,那i不能等于6,因为 p = p->next,在第5个位置之后满了,p指向NULL,下一步p->next出错了,根本找不到表的某个位置
17         return false;
18     LNode *s = (LNode *)malloc(sizeof(LNode));//创建一个节点,这个节点的数据域就是e
19     s->data = e;
20     s->next = p->next;  //自己画图理解,一开始p后的节点不是s,这里让p的下一个节点变成了在s的下一个节点
21     p->next = s; //将结点s连到p之后
22     return true; //插入成功
23 }

       函数调用。注意:调用之间要把主函数的初始化函数注释打开。

1 case 1: //1,添加数据
2             InsertList(L,1,1);
3             InsertList(L,2,2);
4             InsertList(L,3,3);
5             InsertList(L,4,4);
6             InsertList(L,5,5);
7             printf("数据添加成功!\n");
8             getchar();
9             break;

 

      运行结果显示:

     5 ,deleteAtIndex(index):如果索引 index 有效,则删除链表中的第 index 个节点。删除思路和今天的第一道一样。

 1 bool DeleteList(LinkList &L, int i)//删除表L中第 i 个位置的元素,并用e返回删除元素的值。
 2 {
 3     if(i < 1)
 4         return false;
 5     LNode *p;
 6     p = L;
 7     int j = 0;
 8     while(p != NULL && j < i - 1) //循环找第 i-1 个节点
 9     {
10         p = p->next;
11         j++;
12     }
13     if(p == NULL) //i值不合法,导致第 i-1 个节点根本在表中找不到
14         return false;
15     if(p->next == NULL) //第 i-1 个节点能找到,但是刚好第 i-1 个节点之后已无其他节点(第i个结点和第i+1个节点没有了),那就没有办法把第 i-1 个节点的指向下一个节点的指针指向第 i+1 个节点
16         return false;
17     LNode *q = p->next; //p是第 i-1 个节点,p->next是之后的节点,也是第 i 个节点,令q指向被删除节点
18     p->next = q->next; //将*q 节点从链中断开,重新更改指针p的指向,指向第 i + 1个节点
19     free(q); //释放节s点的存储空间
20     return true;
21 } 
      函数调用。
1 case 2: //2,删除数据
2             DeleteList(L,1);
3             getchar();
4             break;
     运行结果显示:

 

       完整代码实现:

  1 #include <stdio.h>
  2 #include <malloc.h>
  3 typedef struct LNode{ //定义单链表结点类型    //这种方式代码可读性更强
  4     int data;//每个节点存放一个数据元素
  5     struct LNode *next;//指针指向下一个节点
  6 }LNode, *LinkList; //LNode 是struct LNode 的别名,LinkList是struct LNode *的别名,指针指向整个结构体
  7 bool InitList(LinkList &L) //初始化一个单链表(带头结点)
  8 {
  9     L = (LNode *)malloc(sizeof(LNode)); //分配一个头节点,malloc函数强调返回是一个节点(LNode *),如果单链表有头节点,则头指针指向头节点,即 LinkList L = (LNode *)malloc(sizeof(LNode)); 等号有指向作用
 10     if(L == NULL) //内存不足,分配失败,就没有创建出单链表,因为已经分配了一个节点,所以只能内存不足的原因,空表是没有节点
 11         return false;
 12     L->next = NULL;//目前只有一个头节点,头节点之后暂时还没有节点
 13     return true;
 14 }
 15 bool List_HeadInsert(LinkList &L)//逆向建立单链表
 16 {
 17     LNode *s;
 18     int x;
 19     L = (LNode *)malloc(sizeof(LNode)); //创建头结点
 20     L->next = NULL; //初始为空链表,养成好习惯,只要是初始化单链表,都先把头指针指向NULL
 21     scanf("%d",&x);
 22     while(x != 9999)
 23     {
 24         s = (LNode *)malloc(sizeof(LNode));    //第10行到第13行代码和后插操作InsertNextNode函数第5行到第10行代码是等同的
 25         s->data = x;
 26         s->next = L->next;//把新结点插入到头结点之后
 27         L->next = s;//更改头指针指向
 28         scanf("%d",&x);
 29     }
 30     return true;
 31 }
 32 bool List_TailInsert(LinkList &L) //正向建立单链表
 33 {
 34     int x; //插入的元素
 35     L = (LinkList)malloc(sizeof(LNode));//建立头结点
 36     LNode *s, *r = L; //声明结点,s是把插入的元素放在结点s,r为表尾指针,让s,r初始化指向,头结点
 37      L->next = NULL; //初始为空链表
 38     scanf("%d",&x);
 39     while(x != 9999) //输入9999表示结束,任意的一个数字
 40     {
 41         s = (LNode *)malloc(sizeof(LNode)); //分配插入的结点
 42         s->data = x;
 43         r->next = s; //在r结点之后插入元素x
 44         r = s; //永远保持r指向最后一个结点
 45         scanf("%d",&x);
 46      }
 47     r->next = NULL; //插入数字完后,再把尾结点指针置空
 48     return true; //返回链表L
 49 } //时间复杂度为O(n)
 50 bool InsertList(LinkList &L, int i, int e) //在第 i 个位置插入元素 e (带头结点)
 51 {
 52     if(i < 1) //只能在头结点之后插入,头结点是第0个,之后是第1个
 53     {
 54         List_HeadInsert(L); //头插法 
 55     }
 56     
 57     LNode *p; //LNode * 强调这是一个结点,声明一个结点,表示指针p指向当前找到的结点
 58     p = L; //L是指向头结点的头指针,再把刚开始的指针p指向L,表示目前的指针p指向头结点
 59     int j = 0;//记录当前p指向的是第几个结点,从头结点0开始
 60     while(p!= NULL && j < i - 1) //循环找到第 i-1 个结点,j = i-1,不进入循环,内存满了,不进入循环
 61     {
 62         p = p->next; //p指向下一个结点
 63         j++;
 64     }
 65     if(p==NULL) //i值不合法,如果有4个结点,那i不能等于6,因为 p = p->next,在第5个位置之后满了,p指向NULL,下一步p->next出错了,根本找不到表的某个位置
 66         return false;
 67     LNode *s = (LNode *)malloc(sizeof(LNode));//创建一个节点,这个节点的数据域就是e
 68     s->data = e;
 69     s->next = p->next;  //自己画图理解,一开始p后的节点不是s,这里让p的下一个节点变成了在s的下一个节点
 70     p->next = s; //将结点s连到p之后
 71     return true; //插入成功
 72 }
 73 void ShowList(LinkList L) //显示
 74 {
 75     if(L->next == NULL)
 76        printf("这是一个空表\n");
 77     while(L != NULL)
 78     {
 79         L = L->next;
 80         printf("%d ",L->data);
 81     }
 82 
 83 }
 84 bool DeleteList(LinkList &L, int i)//删除表L中第 i 个位置的元素,并用e返回删除元素的值。
 85 {
 86     if(i < 1)
 87         return false;
 88     LNode *p;
 89     p = L;
 90     int j = 0;
 91     while(p != NULL && j < i - 1) //循环找第 i-1 个节点
 92     {
 93         p = p->next;
 94         j++;
 95     }
 96     if(p == NULL) //i值不合法,导致第 i-1 个节点根本在表中找不到
 97         return false;
 98     if(p->next == NULL) //第 i-1 个节点能找到,但是刚好第 i-1 个节点之后已无其他节点(第i个结点和第i+1个节点没有了),那就没有办法把第 i-1 个节点的指向下一个节点的指针指向第 i+1 个节点
 99         return false;
100     LNode *q = p->next; //p是第 i-1 个节点,p->next是之后的节点,也是第 i 个节点,令q指向被删除节点
101     p->next = q->next; //将*q 节点从链中断开,重新更改指针p的指向,指向第 i + 1个节点
102     free(q); //释放节s点的存储空间
103     return true;
104 }
105 int GetList(LinkList &L, int i)//按位查找,返回第 i 个元素(带头节点)
106 {
107     if(i < 0)//有头节点,头节点是第0个节点,所以查找元素i不能小于0
108         return -1;
109     LNode *p;
110     int j = 0;
111     p = L;
112     while(p != NULL && j < i) //找的是第i个节点,插入那里找的是第i-1 个节点
113     {  //如果i大于表的长度,那循环找到的p会指向NULL,不会进入循环体,最后返回NULL
114         p = p->next;
115         j++;
116     }
117     return p->data;
118 } //平均时间复杂度为O(n)
119 int UpdateList(LinkList &L, int i, int num)
120 {
121    if(i < 0)//有头节点,头节点是第0个节点,所以查找元素i不能小于0
122         return 0;
123     LNode *p;
124     int j = 0;
125     p = L;
126     while(p != NULL && j < i) //找的是第i个节点,插入那里找的是第i-1 个节点
127     {  //如果i大于表的长度,那循环找到的p会指向NULL,不会进入循环体,最后返回NULL
128         p = p->next;
129         j++;
130     }
131     p->data = num;
132     return p->data;
133 }
134 void Destroy(LinkList &L) //销毁单链表
135 {
136     LNode *p;
137     while(L != NULL)
138     {
139         p = L;
140         L = L->next;
141         free(p);
142     }
143 }
144 void ShowMenu()
145 {
146     printf("************************\n");
147     printf("*****  1,添加数据  *****\n");
148     printf("*****  2,删除数据  *****\n");
149     printf("*****  3,查找数据  *****\n");
150     printf("*****  4,修改数据  *****\n");
151     printf("*****  5,显示数据  *****\n");
152     printf("*****  6,头插法    *****\n");
153     printf("*****  7,尾插法    *****\n");
154     printf("*****  0,销毁并退出  ***\n");
155 }
156 int main()
157 {
158     LinkList L;//声明一个单链表
159     InitList(L);//初始化函数调用
160 
161     int select = 0; //创建选择输入的变量
162     while (true)
163     {
164         //菜单调用
165         ShowMenu();
166         printf("请输入你的选择\n");
167         scanf("%d", &select);
168         switch (select)
169         {
170         case 1: //1,添加数据
171             InsertList(L,1,1);
172             InsertList(L,2,2);
173             InsertList(L,3,3);
174             InsertList(L,4,4);
175             InsertList(L,5,5);
176             printf("数据添加成功!\n");
177             getchar();
178             break;
179         case 2: //2,删除数据
180             DeleteList(L,1);
181             getchar();
182             break;
183         case 3: //3,查找数据
184             printf("查找的元素是:%d\n",GetList(L,1));
185             getchar();
186             break;
187         case 4: //4,修改数据
188             UpdateList(L,1,0);
189             printf("修改成功!\n");
190             getchar();
191             break;
192         case 5: //4,显示数据
193             printf("单链表的数据有:");
194             ShowList(L);
195             getchar();
196             break;
197         case 6: //头插法 
198             List_HeadInsert(L); 
199             getchar();
200             break;
201         case 7: //尾插法
202             List_TailInsert(L);
203             getchar();
204             break;
205         case 0: //0,退出
206             Destroy(L);
207             printf("单链表已销毁!");
208             printf("欢迎下次使用");
209             return 0;
210             break;
211 
212         default:
213             break;
214         }
215     }
216     return 0;
217 }

206.反转链表 

       题目链接/文章讲解/视频讲解:https://programmercarl.com/0206.%E7%BF%BB%E8%BD%AC%E9%93%BE%E8%A1%A8.html

    卡哥题目建议:建议先看我的视频讲解,视频讲解中对 反转链表需要注意的点讲的很清晰了,看完之后大家的疑惑基本都解决了。      做题思路:

       链表的反转就是链表的逆置,从上个题就能看出,头插法是链表的逆置。

       代码见上个题的。

 

标签:结点,LNode,int,随想录,next,链表,移除,NULL,节点
From: https://www.cnblogs.com/romantichuaner/p/17587197.html

相关文章

  • 数据结构之带头节点的单链表增删改查操作实现
     单链表的定义什么是单链表   单链表是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素。   单链表的各个数据元素在物理上可以是离散存放的,每个结点除了存放数据元素外,还要存储指向下一个节点的指针。而顺序表是连续存放的,每个结点中只......
  • 链表/栈/队列/KMP
    链表用数组模拟,不同于结构体加指针调用new关键字开上万级别的节点非常慢,基本会超时单链表来构造邻接表用于存图与树基本结构:head表示头结点的下标e[i]表示节点i的值ne[i]表示节点i的下一个节点的下标idx存储当前已经用到了哪个节点,表示新节点基本操作:......
  • ehcache模糊批量移除缓存
    目录前言实现总结前言众所周知,encache是现在最流行的java开源缓存框架,配置简单,结构清晰,功能强大。通过注解@Cacheable可以快速添加方法结果到缓存。通过@CacheEvict可以快速清除掉指定的缓存。但由于@CacheEvict注解使用的是key-value的,不支持模糊删除,就会遇到问......
  • 代码随想录算法训练营第四十天| 300.最长递增子序列 674. 最长连续递增序列 718.
    300.最长递增子序列要求:可以删减任意个节点,最后保存最大的递增长度难点:410489如何保证全局的视角,看到很前面的节点是否大于当前的节点,而不是仅仅记录状态思路:dp[n],当子序列的末尾为N时,它的最大子序列长度也就意味着,N在它的子序列中是最大的,遍历这个N之前的所有序......
  • 代码随想录算法训练营第二天| LeetCode 977.有序数组的平方 ,209.长度最小的子数组 ,59.
    977.有序数组的平方     题目链接:https://leetcode.cn/problems/squares-of-a-sorted-array/    文章讲解:https://programmercarl.com/0977.%E6%9C%89%E5%BA%8F%E6%95%B0%E7%BB%84%E7%9A%84%E5%B9%B3%E6%96%B9.html    视频讲解: https://www.bili......
  • 单链表查找与删除
    单链表是一种常见的数据结构,它由一系列的节点组成,每个节点包含一个数据元素和一个指向下一个节点的指针。在单链表中,查找和删除节点是常见的操作。1.单链表查找:要查找单链表中的一个节点,需要从链表的头节点开始,沿着指针依次遍历每个节点,直到找到目标节点或者到达链表的末尾(即指针......
  • [代码随想录]Day02-数组part02
    题目:977.有序数组的平方思路:一开始的思路是从中间向两边扩:找到第一个大于等于0的位置r;判断nums[r]是否大于等于0,如果不是赋值为len(nums)表示不在范围内了。l的位置在r的左侧因此l=r-1只要l>=0或者r<len(nums)满足一个就可以继续;遍历时要保证数组不能越界说实话维护......
  • 数据结构练习笔记——求解由单链表表示的一元多项式的值
    求解由单链表表示的一元多项式的值【问题描述】一个形如\[a_0x^0+a_1x^1+...+a_nx^n\]的一元多项式含有n+1项,每一项由系数和指数唯一确定,可表示成由系数项和指数项构成的一个二元组(系数,指数),一元多项式则可以表示成二元组的集合{(a0,0),(a1,1),(a2,2)...(an,n)},可看成是数据......
  • [代码随想录]Day01-数组part01
    题目:704.二分查找思路:二分查找一般是在有序的数组中查找指定的值,单纯的查找值,把数组跑一遍的复杂度为O(n)。二分查找每次把范围缩小一半,我们每次都去中间的值,有以下三种情况:如果mid位置的值比target大,那么target应该在mid左侧的位置(由小到大排序情况下)如果mid位置的值比t......
  • 问题--链表指针传参,修改next指针只传值
    1.问题--链表指针传参,修改next指针只传值Link_creat_head(&head,p_new);//将新节点加入链表在这当中head头指针传的是地址,而p_new传的是值,这二者有什么区别?#include<stdio.h>#include<stdlib,h>//定义结点结构体typedefstructstudent{//数据域intnum;......