当前位置:   article > 正文

线性表(单链表)的存储结构和基本操作(初始化,创建,取值,查找,插入,删除)_完成线性表的基本操作实现(初始化单链表、判断是否为空表、插入(至少插入5个数据)

完成线性表的基本操作实现(初始化单链表、判断是否为空表、插入(至少插入5个数据)

目录

单链表的存储结构

单链表的基本操作实现

1、初始化

2、创建单链表

(1)前插法

(2)后插法

3、单链表的取值

4、单链表的查找 

5、单链表插入元素

6、单链表删除元素

整体代码:

运行截图​编辑


在单链表中,对于数据元素a_{i}来说,除了存储其本身的信息外,还需要存储有关于其直接后继的信息(直接后继的存储位置),这两部分信息组成数据元素a_{i}的存储映像,称为结点,它包括两个域,存储数据元素信息的域称为数据域,存储直接后继存储位置的域称为指针域

单链表的存储结构

由一个结点是由数据域和指针域构成的,可以用代码表示出单链表的存储结构

  1. typedef struct LNode{
  2. ElemType date;//结点的数据域,用来存储自身的信息
  3. struct LNode *next;//结点的指针域,用来指向一整个结点
  4. }LNode,*LinkList;//对同一结构体指针类型起了两个名称

LinkList与LNode*,两者本质上是相等的,都是结构体指针类型的名称,但两者所强调内容不一样:

1、用LinkList定义单链表,强调定义的是某个单链表的头指针(指向列表中第一个结点的针),例如LinkList L,则L为单链表的头指针。

2、用LNode *定义指向单链表中任意结点的指针变量,例如LNode *p,则p为指向单链表中某个结点的指针,用*p代表该结点

(若定义LinkList p 或者 LNode *p,则p表示指向某结点的指针变量,表示该结点的地址,而*p为对应的结点变量,表示该结点的名称)

链表的基本操作实现

1、初始化

操作步骤:

  1. 要生成一个新的头结点,让头指针L指向头结点,
  2. 将头结点的指针域置空,代码如下:

算法描述: 

  1. Status InitList(LinkList &L)
  2. {
  3. L=new LNode;//生成新的头结点,并让头指针L指向头结点
  4. L->next=NULL;//将头结点的指针域置空
  5. return OK;
  6. }

2、创建单链表

(1)前插法

操作步骤:

  1. 创建一个只有头结点的空链表
  2. 根据列表中即将输入的元素个数n,执行以下操作n次

                1)创建一个新的结点,并使指针p指向该节点

                2)输入该结点的数据域,即p->data

                3)  修改p的指针域为L的指针域,并将L的指针域指向新 生成的结点p

算法描述:

  1. void CreatList_Q(LinkList &L,int n)
  2. {
  3.     L=new LNode;
  4.     L->next=NULL;
  5.     for(i=0;i<n;i++){
  6.         p=new LNode;
  7.         cin>>p->date;
  8.         p->next=L->next;L->next=p;
  9.     }
  10. }

(2)后插法

操作步骤:

  1. 创建一个只有头结点的空链表
  2. 引入一个指针变量r,让指针r始终指向该链表的最后一个结点(开始时r=L)
  3. 根据列表中即将输入的元素个数n,执行以下操作n次

                1)创建一个新的结点,并使指针p指向该节点

                2)输入该结点的数据域,即p->data

                3)将p的指针域置空并将r的指针域指向结点p

                4)让指针p指向r(保证指针r指向该链表的最后一个结点)

算法描述: 

  1. void CreatList_H(LinkList &L,int n)
  2. {
  3.     L=new LNode;
  4.     L->next=NULL;
  5.     r=L;
  6.     for(i=0;i<n;i++){
  7.         p=new LNode;
  8.         cin>>p->data;
  9.         p->next=NULL;r->next=p;
  10.         r=p;
  11.     }

3、单链表的取值

操作步骤:

  1. 引入指针p ,让指针p指向首元结点,并引入计数器j
  2. 当指针p所指结点不为空并且计数器j的值小于i的值时进行以下循环

                1)p指向下一个结点

                2)计数器的值加1 

     3.当p为NULL时或者计数器j的值大于i的值,找到安全出口(return ERROR)

     4.当计数器j的值等于i的值时,将指针p所指结点的数据域赋值给e,并安全推出

算法描述:

  1. Status GetElem(LinkList L,int i,ElemType &e)
  2. {
  3. p=L->next;j=1;
  4. while(p!=NULL && j<i)
  5. {
  6. p=p->next;
  7. j++;
  8. }
  9. if(p==NULL || j>i) return ERROR;
  10. e=p->data;
  11. return OK;
  12. }

4、单链表的查找 

单链表的查找返回的为地址,则返回类型应为LNode *或者LinkList

(两者本质上没有区别,但是:

习惯用LinkList强调定义的是某个单链表的头指针,如LinkList L

习惯用LNode *定义指向单链表中任意结点的指针变量,如LNode *p)

操作步骤:

  1. 引入指针p指向首元结点,当p所指结点的指针域不为空且p所指结点的数据域与传入值e不相等时,执行以下操作:

                1)指针p指向下一结点的位置(p=p->next)

     2.返回指针p所指结点(即地址)

  1. LNode *LocateElem(LinkList L,ElemType e)
  2. {
  3. p=L->next;//p指向首元结点
  4. while(p!=NULL && p->date!=e)
  5. p=p->next;//p指向下一个结点
  6. return p;//查找成功返回e的结点地址,否则返回NULL
  7. }

5、单链表插入元素

操作步骤:

1.引入指针变量p指向头结点,并引入计数器,将计数器的初始值赋值为0

2.当p所指结点不为空且 j < i-1时,循环进行以下操作:

  • 指针p指向下一结点的位置(p=p->next)
  • 计数器加1

3.退出循环如果是因为i>n+1(p==NULL)或者是i<1(j>i-1),需要安全退出(return ERROR) 

4.如果不是因为以上两个条件推出,则说明找到了插入位置(j==i-1),生成一个新的结点,并使指针s指向新生成的结点

5.将e的值写入新生成的结点中

6.将p的next域赋值给s的next的域

7.将p的next域指向结点s

8.正常退出(return OK)

算法描述: 

  1. Status ListInsert(LinkList &L,int i,ElemType e)
  2. {
  3. p=L;j=0;
  4. while(p!=NULL && (j<i-1))
  5. {p=p->next;j++;}
  6. if(p==NULL || j>i-1) return ERROR;
  7. s=new LNode;
  8. s->date=e;
  9. s->next=p->next;
  10. p->next=s;
  11. return OK;
  12. }

6、单链表删除元素

操作步骤:

1.引入指针变量p指向头结点,并引入计数器,将计数器的初始值赋值为0

2.当p的next域所指结点不为空且 j <  i-1时,循环进行以下操作:

  • 指针p指向下一结点的位置(p=p->next)
  • 计数器加1

3.退出循环如果是因为i>n(p->next==NULL)或者是i<1(j>i-1),需要安全退出(return ERROR) 

4.如果不是因为以上两个条件推出,则说明找到了删除位置(j==i-1)

5.将p的next域赋值给q

6.将q的next域赋值给p的next域

7.释放删除结点所占空间

8.正常退出(return OK)

算法描述: 

  1. Status ListDelete(LinkList &L,int i)
  2. {
  3. p=L;j=0;
  4. while((p->next!=NULL) && (j<i-1))
  5. {p=p->next;j++;}
  6. if(p->next==NULL || (j>i-1)) return ERROR;
  7. q=p->next;
  8. p->next=q->next;
  9. delete q;
  10. return OK;
  11. }

整体代码:

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. typedef int ElemType;
  4. typedef int Status;
  5. #define OK 1
  6. #define ERROR 0
  7. //单链表的存储结构
  8. typedef struct LNode{
  9. ElemType data;//结点的数据域,用来存储自身的信息
  10. struct LNode *next;//结点的指针域,用来指向一整个结点
  11. }LNode,*LinkList;//对同一结构体指针类型起了两个名称
  12. //单链表的初始化
  13. Status InitList(LinkList &L)
  14. {
  15. L=new LNode;//生成新的头结点,并让头指针L指向头结点
  16. L->next=NULL;//将头结点的指针域置空
  17. return OK;
  18. }
  19. //前插法创建单链表
  20. void CreatList_Q(LinkList &L,int n)
  21. {
  22. LNode *p;
  23. L=new LNode;
  24. L->next=NULL;
  25. cout<<"请输入"<<n<<"个元素"<<endl;
  26. for(int i=0;i<n;i++){
  27. p=new LNode;
  28. cin>>p->data;
  29. p->next=L->next;L->next=p;
  30. }
  31. }
  32. //后插法创建单链表
  33. void CreatList_H(LinkList &L,int n)
  34. {
  35. LNode *p,*r;
  36. L=new LNode;
  37. L->next=NULL;
  38. r=L;
  39. cout<<"请输入"<<n<<"个元素"<<endl;
  40. for(int i=0;i<n;i++){
  41. p=new LNode;
  42. cin>>p->data;
  43. p->next=NULL;r->next=p;
  44. r=p;
  45. }
  46. }
  47. //单链表的取值
  48. Status GetElem(LinkList L,int i,ElemType &e)
  49. {
  50. LNode *p;
  51. p=L->next;
  52. int j=1;
  53. while(p!=NULL && j<i)
  54. {
  55. p=p->next;
  56. j++;
  57. }
  58. if(p==NULL || j>i) return ERROR;
  59. e=p->data;
  60. return OK;
  61. }
  62. //单链表的查找
  63. LNode *LocateElem(LinkList L,ElemType e)
  64. {
  65. LNode *p;
  66. p=L->next;//p指向首元结点
  67. while(p!=NULL && p->data!=e)
  68. p=p->next;//p指向下一个结点
  69. return p;//查找成功返回e的结点地址,否则返回NULL
  70. }
  71. //单链表插入元素
  72. Status ListInsert(LinkList &L,int i,ElemType e)
  73. {
  74. LNode *p,*s;
  75. p=L;
  76. int j=0;
  77. while(p!=NULL && (j<i-1))
  78. {p=p->next;j++;}
  79. if(p==NULL || j>i-1) return ERROR;
  80. s=new LNode;
  81. s->data=e;
  82. s->next=p->next;
  83. p->next=s;
  84. return OK;
  85. }
  86. //单链表删除元素
  87. Status ListDelete(LinkList &L,int i)
  88. {
  89. LNode *p,*q;
  90. p=L;
  91. int j=0;
  92. while((p->next!=NULL) && (j<i-1))
  93. {p=p->next;j++;}
  94. if(p->next==NULL || (j>i-1)) return ERROR;
  95. q=p->next;
  96. p->next=q->next;
  97. delete q;
  98. return OK;
  99. }
  100. //单链表的遍历
  101. void Display(LinkList L)
  102. {
  103. LNode *p;
  104. p=L->next;
  105. cout<<"当前单链表为:"<<endl;
  106. while(p!=NULL){
  107. cout<<p->data<<" ";
  108. p=p->next;
  109. }
  110. cout<<endl;
  111. }
  112. int main()
  113. {
  114. LinkList L;
  115. int k;
  116. k=InitList(L);
  117. if(k==0) cout<<"初始化失败!";
  118. else{
  119. cout<<"初始化成功!"<<endl;
  120. int n,h;
  121. cout<<"请输入您要存储的元素的个数:";
  122. cin>>n;
  123. CreatList_H(L,n);
  124. Display(L);
  125. cout<<"1:对单链表中的元素进行取值"<<endl;
  126. cout<<"2:查找单链表中元素的位置"<<endl;
  127. cout<<"3:在单链表中插入一个元素"<<endl;
  128. cout<<"4:删除单链表中的一个元素"<<endl<<"5:退出"<<endl;
  129. while(1){
  130. cout<<"请输入您的选择:";
  131. cin>>h;
  132. if(h==1){
  133. ElemType e;
  134. int i;
  135. cout<<"请输入您要查询的是第几个元素:";
  136. cin>>i;
  137. GetElem(L,i,e);
  138. cout<<"该元素为:"<<e<<endl;
  139. }
  140. else if(h==2){
  141. ElemType e;
  142. LNode *g;
  143. cout<<"请输入您要查询的元素:";
  144. cin>>e;
  145. g=LocateElem(L,e);
  146. cout<<"该结点的地址为:"<<g<<endl;
  147. }
  148. else if(h==3){
  149. int i;
  150. ElemType e;
  151. cout<<"请输入您要插入的位置及元素:";
  152. cin>>i>>e;
  153. ListInsert(L,i,e);
  154. Display(L);
  155. }
  156. else if(h==4){
  157. int i;
  158. cout<<"请输入您要删除元素的位置:";
  159. cin>>i;
  160. ListDelete(L,i);
  161. Display(L);
  162. }
  163. else if(h==5) {cout<<"退出成功!";break;}
  164. }
  165. }
  166. return 0;
  167. }

运行截图 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/470574
推荐阅读
相关标签
  

闽ICP备14008679号