[C.C++] 数据结构C代码汇总【1-线性表】

397 0
Honkers 2025-5-4 10:36:18 | 显示全部楼层 |阅读模式

 下面直接往下看源代码及注释即可,注意,每一种数据结构都是按照数据结构定义+基本运算算法代码实现汇总在一起(包含常见算法的代码实现),这样在回顾数据结构的同时,掌握基本运算算法的代码实现,掌握住这些基础算法,就不用担心考研题目没思路了!

一、线性表

1、顺序表

  1. //顺序表运算算法
  2. #include <stdio.h>
  3. #include <malloc.h>
  4. #define MaxSize 50
  5. typedef char ElemType;
  6. typedef struct
  7. { ElemType data[MaxSize]; //存放顺序表元素
  8. int length; //存放顺序表的长度
  9. } SqList; //声明顺序表的类型
  10. void CreateList(SqList *&L,ElemType a[],int n) //整体建立顺序表
  11. {
  12. L=(SqList *)malloc(sizeof(SqList));
  13. for (int i=0;i<n;i++)
  14. L->data[i]=a[i];
  15. L->length=n;
  16. }
  17. void InitList(SqList *&L) //初始化线性表
  18. {
  19. L=(SqList *)malloc(sizeof(SqList)); //分配存放线性表的空间
  20. L->length=0;
  21. }
  22. void DestroyList(SqList *&L) //销毁线性表
  23. {
  24. free(L);
  25. }
  26. bool ListEmpty(SqList *L) //判线性表是否为空表
  27. {
  28. return(L->length==0);
  29. }
  30. int ListLength(SqList *L) //求线性表的长度
  31. {
  32. return(L->length);
  33. }
  34. void DispList(SqList *L) //输出线性表
  35. {
  36. for (int i=0;i<L->length;i++)
  37. printf("%c ",L->data[i]); //若是int类型,就改为%d即可,注意细节
  38. printf("\n");
  39. }
  40. bool GetElem(SqList *L,int i,ElemType &e) //求线性表中第i个元素值
  41. {
  42. if (i<1 || i>L->length)
  43. return false;
  44. e=L->data[i-1];
  45. return true;
  46. }
  47. int LocateElem(SqList *L, ElemType e) //查找第一个值域为e的元素序号
  48. {
  49. int i=0;
  50. while (i<L->length && L->data[i]!=e) i++;
  51. if (i>=L->length)
  52. return 0;
  53. else
  54. return i+1;
  55. }
  56. bool ListInsert(SqList *&L,int i,ElemType e) //插入第i个元素
  57. {
  58. int j;
  59. if (i<1 || i>L->length+1)
  60. return false;
  61. i--; //将顺序表位序转化为elem下标
  62. for (j=L->length;j>i;j--) //将data[i]及后面元素后移一个位置
  63. L->data[j]=L->data[j-1];
  64. L->data[i]=e;
  65. L->length++; //顺序表长度增1
  66. return true;
  67. }
  68. bool ListDelete(SqList *&L,int i,ElemType &e) //删除第i个元素
  69. {
  70. int j;
  71. if (i<1 || i>L->length)
  72. return false;
  73. i--; //将顺序表位序转化为elem下标
  74. e=L->data[i];
  75. for (j=i;j<L->length-1;j++) //将data[i]之后的元素前移一个位置
  76. L->data[j]=L->data[j+1];
  77. L->length--; //顺序表长度减1
  78. return true;
  79. }
复制代码

2、单链表

  1. //单链表运算算法
  2. #include <stdio.h>
  3. #include <malloc.h>
  4. typedef char ElemType;
  5. typedef struct LNode
  6. {
  7. ElemType data;
  8. struct LNode *next; //指向后继结点
  9. } LinkNode; //单链表结点类型
  10. void CreateListF(LinkNode *&L,ElemType a[],int n)
  11. //头插法建立单链表
  12. {
  13. LinkNode *s;
  14. L=(LinkNode *)malloc(sizeof(LinkNode)); //创建头结点
  15. L->next=NULL;
  16. for (int i=0;i<n;i++)
  17. {
  18. s=(LinkNode *)malloc(sizeof(LinkNode));//创建新结点s
  19. s->data=a[i];
  20. s->next=L->next; //将结点s插在原开始结点之前,头结点之后
  21. L->next=s;
  22. }
  23. }
  24. void CreateListR(LinkNode *&L,ElemType a[],int n)
  25. //尾插法建立单链表
  26. {
  27. LinkNode *s,*r;
  28. L=(LinkNode *)malloc(sizeof(LinkNode)); //创建头结点
  29. L->next=NULL;
  30. r=L; //r始终指向尾结点,开始时指向头结点
  31. for (int i=0;i<n;i++)
  32. {
  33. s=(LinkNode *)malloc(sizeof(LinkNode));//创建新结点s
  34. s->data=a[i];
  35. r->next=s; //将结点s插入r结点之后
  36. r=s;
  37. }
  38. r->next=NULL; //尾结点next域置为NULL
  39. }
  40. void InitList(LinkNode *&L) //初始化线性表
  41. {
  42. L=(LinkNode *)malloc(sizeof(LinkNode)); //创建头结点
  43. L->next=NULL; //单链表置为空表
  44. }
  45. void DestroyList(LinkNode *&L) //销毁线性表
  46. {
  47. LinkNode *pre=L,*p=pre->next;
  48. while (p!=NULL)
  49. { free(pre);
  50. pre=p; //pre、p同步后移一个结点
  51. p=pre->next;
  52. }
  53. free(pre); //此时p为NULL,pre指向尾结点,释放它
  54. }
  55. bool ListEmpty(LinkNode *L) //判线性表是否为空表
  56. {
  57. return(L->next==NULL);
  58. }
  59. int ListLength(LinkNode *L) //求线性表的长度
  60. { int i=0;
  61. LinkNode *p=L; //p指向头结点,n置为0(即头结点的序号为0)
  62. while (p->next!=NULL)
  63. { i++;
  64. p=p->next;
  65. }
  66. return(i); //循环结束,p指向尾结点,其序号i为结点个数
  67. }
  68. void DispList(LinkNode *L) //输出线性表
  69. { LinkNode *p=L->next; //p指向首结点
  70. while (p!=NULL) //p不为NULL,输出p结点的data域
  71. { printf("%c ",p->data); //若是int类型,改为%d即可,注意细节
  72. p=p->next; //p移向下一个结点
  73. }
  74. printf("\n");
  75. }
  76. bool GetElem(LinkNode *L,int i,ElemType &e) //求线性表中第i个元素值
  77. { int j=0;
  78. if (i<=0) return false; //i错误返回假
  79. LinkNode *p=L; //p指向头结点,j置为0(即头结点的序号为0)
  80. while (j<i && p!=NULL) //找第i个结点p
  81. { j++;
  82. p=p->next;
  83. }
  84. if (p==NULL) //不存在第i个数据结点,返回false
  85. return false;
  86. else //存在第i个数据结点,返回true
  87. { e=p->data;
  88. return true;
  89. }
  90. }
  91. int LocateElem(LinkNode *L,ElemType e) //查找第一个值域为e的元素序号
  92. { int i=1;
  93. LinkNode *p=L->next; //p指向首结点,i置为1(即首结点的序号为1)
  94. while (p!=NULL && p->data!=e) //查找data值为e的结点,其序号为i
  95. { p=p->next;
  96. i++;
  97. }
  98. if (p==NULL) //不存在值为e的结点,返回0
  99. return(0);
  100. else //存在值为e的结点,返回其逻辑序号i
  101. return(i);
  102. }
  103. bool ListInsert(LinkNode *&L,int i,ElemType e) //插入第i个元素
  104. { int j=0;
  105. if (i<=0) return false; //i错误返回假
  106. LinkNode *p=L,*s; //p指向头结点,j置为0(即头结点的序号为0)
  107. while (j<i-1 && p!=NULL) //查找第i-1个结点p
  108. { j++;
  109. p=p->next;
  110. }
  111. if (p==NULL) //未找到第i-1个结点,返回false
  112. return false;
  113. else //找到第i-1个结点p,插入新结点并返回true
  114. { s=(LinkNode *)malloc(sizeof(LinkNode));
  115. s->data=e; //创建新结点s,其data域置为e
  116. s->next=p->next; //将结点s插入到结点p之后
  117. p->next=s;
  118. return true;
  119. }
  120. }
  121. bool ListDelete(LinkNode *&L,int i,ElemType &e) //删除第i个元素
  122. { int j=0;
  123. if (i<=0) return false; //i错误返回假
  124. LinkNode *p=L,*q; //p指向头结点,j置为0(即头结点的序号为0)
  125. while (j<i-1 && p!=NULL) //查找第i-1个结点
  126. { j++;
  127. p=p->next;
  128. }
  129. if (p==NULL) //未找到第i-1个结点,返回false
  130. return false;
  131. else //找到第i-1个结点p
  132. { q=p->next; //q指向第i个结点
  133. if (q==NULL) //若不存在第i个结点,返回false
  134. return false;
  135. e=q->data;
  136. p->next=q->next; //从单链表中删除q结点
  137. free(q); //释放q结点
  138. return true; //返回true表示成功删除第i个结点
  139. }
  140. }
复制代码

3、循环单链表

  1. //循环单链表运算算法
  2. #include <stdio.h>
  3. #include <malloc.h>
  4. typedef int ElemType;
  5. typedef struct LNode //定义单链表结点类型
  6. {
  7. ElemType data;
  8. struct LNode *next;
  9. } LinkNode;
  10. void CreateListF(LinkNode *&L,ElemType a[],int n) //头插法建立循环单链表
  11. {
  12. LinkNode *s;int i;
  13. L=(LinkNode *)malloc(sizeof(LinkNode)); //创建头结点
  14. L->next=NULL;
  15. for (i=0;i<n;i++)
  16. {
  17. s=(LinkNode *)malloc(sizeof(LinkNode));//创建新结点
  18. s->data=a[i];
  19. s->next=L->next; //将结点s插在原开始结点之前,头结点之后
  20. L->next=s;
  21. }
  22. s=L->next;
  23. while (s->next!=NULL) //查找尾结点,由s指向它
  24. s=s->next;
  25. s->next=L; //尾结点next域指向头结点
  26. }
  27. void CreateListR(LinkNode *&L,ElemType a[],int n) //尾插法建立循环单链表
  28. {
  29. LinkNode *s,*r;int i;
  30. L=(LinkNode *)malloc(sizeof(LinkNode)); //创建头结点
  31. L->next=NULL;
  32. r=L; //r始终指向终端结点,开始时指向头结点
  33. for (i=0;i<n;i++)
  34. {
  35. s=(LinkNode *)malloc(sizeof(LinkNode));//创建新结点
  36. s->data=a[i];
  37. r->next=s; //将结点s插入结点r之后
  38. r=s;
  39. }
  40. r->next=L; //尾结点next域指向头结点
  41. }
  42. void InitList(LinkNode *&L) //初始化线性表
  43. {
  44. L=(LinkNode *)malloc(sizeof(LinkNode)); //创建头结点
  45. L->next=L;
  46. }
  47. void DestroyList(LinkNode *&L) //销毁线性表
  48. {
  49. LinkNode *pre=L,*p=pre->next;
  50. while (p!=L)
  51. {
  52. free(pre);
  53. pre=p; //pre、p同步后移一个结点
  54. p=pre->next;
  55. }
  56. free(pre); //此时p=L,pre指向尾结点,释放它
  57. }
  58. bool ListEmpty(LinkNode *L) //判线性表是否为空表
  59. {
  60. return(L->next==L);
  61. }
  62. int ListLength(LinkNode *L) //求线性表的长度
  63. {
  64. LinkNode *p=L;int i=0; //p指向头结点,n置为0(即头结点的序号为0)
  65. while (p->next!=L)
  66. {
  67. i++;
  68. p=p->next;
  69. }
  70. return(i); //循环结束,p指向尾结点,其序号n为结点个数
  71. }
  72. void DispList(LinkNode *L) //输出线性表
  73. {
  74. LinkNode *p=L->next;
  75. while (p!=L) //p不为L,输出p结点的data域
  76. {
  77. printf("%d ",p->data);
  78. p=p->next;
  79. }
  80. printf("\n");
  81. }
  82. bool GetElem(LinkNode *L,int i,ElemType &e) //求线性表中第i个元素值
  83. { int j=1;
  84. LinkNode *p=L->next;
  85. if (i<=0 || L->next==L) //i错误或者空表返回假
  86. return false;
  87. if (i==1) //求第1个结点值,作为特殊情况处理
  88. {
  89. e=L->next->data;
  90. return true;
  91. }
  92. else //i不为1时
  93. {
  94. while (j<=i-1 && p!=L) //找第i个结点p
  95. {
  96. j++;
  97. p=p->next;
  98. }
  99. if (p==L) //没有找到返回假
  100. return false;
  101. else //找到了提取它的值并返回整
  102. {
  103. e=p->data;
  104. return true;
  105. }
  106. }
  107. }
  108. int LocateElem(LinkNode *L,ElemType e) //查找第一个值域为e的元素序号
  109. {
  110. LinkNode *p=L->next;
  111. int i=1;
  112. while (p!=L && p->data!=e) //查找第一个值域为e的结点p
  113. {
  114. p=p->next;
  115. i++; //i对应结点p的序号
  116. }
  117. if (p==L)
  118. return(0); //没有找到返回0
  119. else
  120. return(i); //找到了返回其序号
  121. }
  122. bool ListInsert(LinkNode *&L,int i,ElemType e) //插入第i个元素
  123. {
  124. int j=1;
  125. LinkNode *p=L,*s;
  126. if (i<=0) return false; //i错误返回假
  127. if (p->next==L || i==1) //原单链表为空表或i=1作为特殊情况处理
  128. {
  129. s=(LinkNode *)malloc(sizeof(LinkNode)); //创建新结点s
  130. s->data=e;
  131. s->next=p->next; //将结点s插入到结点p之后
  132. p->next=s;
  133. return true;
  134. }
  135. else
  136. {
  137. p=L->next;
  138. while (j<=i-2 && p!=L) //找第i-1个结点p
  139. {
  140. j++;
  141. p=p->next;
  142. }
  143. if (p==L) //未找到第i-1个结点
  144. return false;
  145. else //找到第i-1个结点p
  146. {
  147. s=(LinkNode *)malloc(sizeof(LinkNode)); //创建新结点s
  148. s->data=e;
  149. s->next=p->next; //将结点s插入到结点p之后
  150. p->next=s;
  151. return true;
  152. }
  153. }
  154. }
  155. bool ListDelete(LinkNode *&L,int i,ElemType &e) //删除第i个元素
  156. {
  157. int j=1;
  158. LinkNode *p=L,*q;
  159. if (i<=0 || L->next==L)
  160. return false; //i错误或者空表返回假
  161. if (i==1) //i=1作为特殊情况处理
  162. {
  163. q=L->next; //删除第1个结点
  164. e=q->data;
  165. L->next=q->next;
  166. free(q);
  167. return true;
  168. }
  169. else //i不为1时
  170. {
  171. p=L->next;
  172. while (j<=i-2 && p!=L) //找第i-1个结点p
  173. {
  174. j++;
  175. p=p->next;
  176. }
  177. if (p==L) //未找到第i-1个结点
  178. return false;
  179. else //找到第i-1个结点p
  180. {
  181. q=p->next; //q指向要删除的结点
  182. e=q->data;
  183. p->next=q->next; //从单链表中删除q结点
  184. free(q); //释放q结点
  185. return true;
  186. }
  187. }
  188. }
复制代码

4、双链表

  1. //双链表运算算法
  2. #include <stdio.h>
  3. #include <malloc.h>
  4. typedef int ElemType;
  5. typedef struct DNode
  6. {
  7. ElemType data;
  8. struct DNode *prior; //指向前驱结点
  9. struct DNode *next; //指向后继结点
  10. } DLinkNode; //声明双链表结点类型
  11. void CreateListF(DLinkNode *&L,ElemType a[],int n) //头插法建双链表
  12. {
  13. DLinkNode *s;
  14. L=(DLinkNode *)malloc(sizeof(DLinkNode)); //创建头结点
  15. L->prior=L->next=NULL;
  16. for (int i=0;i<n;i++)
  17. {
  18. s=(DLinkNode *)malloc(sizeof(DLinkNode));//创建新结点
  19. s->data=a[i];
  20. s->next=L->next; //将结点s插在原开始结点之前,头结点之后
  21. if (L->next!=NULL) L->next->prior=s;
  22. L->next=s;s->prior=L;
  23. }
  24. }
  25. void CreateListR(DLinkNode *&L,ElemType a[],int n) //尾插法建双链表
  26. {
  27. DLinkNode *s,*r;
  28. L=(DLinkNode *)malloc(sizeof(DLinkNode)); //创建头结点
  29. L->prior=L->next=NULL;
  30. r=L; //r始终指向终端结点,开始时指向头结点
  31. for (int i=0;i<n;i++)
  32. {
  33. s=(DLinkNode *)malloc(sizeof(DLinkNode));//创建新结点
  34. s->data=a[i];
  35. r->next=s;s->prior=r; //将结点s插入结点r之后
  36. r=s;
  37. }
  38. r->next=NULL; //尾结点next域置为NULL
  39. }
  40. void InitList(DLinkNode *&L) //初始化线性表
  41. {
  42. L=(DLinkNode *)malloc(sizeof(DLinkNode)); //创建头结点
  43. L->prior=L->next=NULL;
  44. }
  45. void DestroyList(DLinkNode *&L) //销毁线性表
  46. {
  47. DLinkNode *pre=L,*p=pre->next;
  48. while (p!=NULL)
  49. {
  50. free(pre);
  51. pre=p; //pre、p同步后移一个结点
  52. p=pre->next;
  53. }
  54. free(p);
  55. }
  56. bool ListEmpty(DLinkNode *L) //判线性表是否为空表
  57. {
  58. return(L->next==NULL);
  59. }
  60. int ListLength(DLinkNode *L) //求线性表的长度
  61. {
  62. DLinkNode *p=L;
  63. int i=0; //p指向头结点,i设置为0
  64. while (p->next!=NULL) //找尾结点p
  65. {
  66. i++; //i对应结点p的序号
  67. p=p->next;
  68. }
  69. return(i);
  70. }
  71. void DispList(DLinkNode *L) //输出线性表
  72. {
  73. DLinkNode *p=L->next;
  74. while (p!=NULL)
  75. {
  76. printf("%c ",p->data);
  77. p=p->next;
  78. }
  79. printf("\n");
  80. }
  81. bool GetElem(DLinkNode *L,int i,ElemType &e) //求线性表中第i个元素值
  82. {
  83. int j=0;
  84. DLinkNode *p=L;
  85. if (i<=0) return false; //i错误返回假
  86. while (j<i && p!=NULL) //查找第i个结点p
  87. {
  88. j++;
  89. p=p->next;
  90. }
  91. if (p==NULL) //没有找到返回假
  92. return false;
  93. else //找到了提取值并返回真
  94. {
  95. e=p->data;
  96. return true;
  97. }
  98. }
  99. int LocateElem(DLinkNode *L,ElemType e) //查找第一个值域为e的元素序号
  100. {
  101. int i=1;
  102. DLinkNode *p=L->next;
  103. while (p!=NULL && p->data!=e) //查找第一个值域为e的结点p
  104. {
  105. i++; //i对应结点p的序号
  106. p=p->next;
  107. }
  108. if (p==NULL) //没有找到返回0
  109. return(0);
  110. else //找到了返回其序号
  111. return(i);
  112. }
  113. bool ListInsert(DLinkNode *&L,int i,ElemType e) //插入第i个元素
  114. {
  115. int j=0;
  116. DLinkNode *p=L,*s; //p指向头结点,j设置为0
  117. if (i<=0) return false; //i错误返回假
  118. while (j<i-1 && p!=NULL) //查找第i-1个结点p
  119. {
  120. j++;
  121. p=p->next;
  122. }
  123. if (p==NULL) //未找到第i-1个结点
  124. return false;
  125. else //找到第i-1个结点p
  126. {
  127. s=(DLinkNode *)malloc(sizeof(DLinkNode)); //创建新结点s
  128. s->data=e;
  129. s->next=p->next; //将结点s插入到结点p之后
  130. if (p->next!=NULL)
  131. p->next->prior=s;
  132. s->prior=p;
  133. p->next=s;
  134. return true;
  135. }
  136. }
  137. bool ListDelete(DLinkNode *&L,int i,ElemType &e) //删除第i个元素
  138. { int j=0;
  139. DLinkNode *p=L,*q; //p指向头结点,j设置为0
  140. if (i<=0) return false; //i错误返回假
  141. while (j<i-1 && p!=NULL) //查找第i-1个结点p
  142. { j++;
  143. p=p->next;
  144. }
  145. if (p==NULL) //未找到第i-1个结点
  146. return false;
  147. else //找到第i-1个节p
  148. { q=p->next; //q指向第i个结点
  149. if (q==NULL) //当不存在第i个结点时返回false
  150. return false;
  151. e=q->data;
  152. p->next=q->next; //从双链表中删除结点q
  153. if (p->next!=NULL) //若p结点存在后继结点,修改其前驱指针
  154. p->next->prior=p;
  155. free(q); //释放q结点
  156. return true;
  157. }
  158. }
复制代码

5、循环双链表

  1. //循环双链表运算算法
  2. #include <stdio.h>
  3. #include <malloc.h>
  4. typedef int ElemType;
  5. typedef struct DNode //定义双链表结点类型
  6. {
  7. ElemType data;
  8. struct DNode *prior; //指向前驱结点
  9. struct DNode *next; //指向后继结点
  10. } DLinkNode;
  11. void CreateListF(DLinkNode *&L,ElemType a[],int n) //头插法建立循环双链表
  12. {
  13. DLinkNode *s;
  14. L=(DLinkNode *)malloc(sizeof(DLinkNode)); //创建头结点
  15. L->next=NULL;
  16. for (int i=0;i<n;i++)
  17. {
  18. s=(DLinkNode *)malloc(sizeof(DLinkNode));//创建新结点
  19. s->data=a[i];
  20. s->next=L->next; //将结点s插在原开始结点之前,头结点之后
  21. if (L->next!=NULL) L->next->prior=s;
  22. L->next=s;s->prior=L;
  23. }
  24. s=L->next;
  25. while (s->next!=NULL) //查找尾结点,由s指向它
  26. s=s->next;
  27. s->next=L; //尾结点next域指向头结点
  28. L->prior=s; //头结点的prior域指向尾结点
  29. }
  30. void CreateListR(DLinkNode *&L,ElemType a[],int n) //尾插法建立循环双链表
  31. {
  32. DLinkNode *s,*r;
  33. L=(DLinkNode *)malloc(sizeof(DLinkNode)); //创建头结点
  34. L->next=NULL;
  35. r=L; //r始终指向尾结点,开始时指向头结点
  36. for (int i=0;i<n;i++)
  37. {
  38. s=(DLinkNode *)malloc(sizeof(DLinkNode));//创建新结点
  39. s->data=a[i];
  40. r->next=s;s->prior=r; //将结点s插入结点r之后
  41. r=s;
  42. }
  43. r->next=L; //尾结点next域指向头结点
  44. L->prior=r; //头结点的prior域指向尾结点
  45. }
  46. void InitList(DLinkNode *&L) //初始化线性表
  47. {
  48. L=(DLinkNode *)malloc(sizeof(DLinkNode)); //创建头结点
  49. L->prior=L->next=L;
  50. }
  51. void DestroyList(DLinkNode *&L) //销毁线性表
  52. {
  53. DLinkNode *pre=L,*p=pre->next;
  54. while (p!=L)
  55. {
  56. free(pre);
  57. pre=p; //pre、p同步后移一个结点
  58. p=pre->next;
  59. }
  60. free(pre); //此时p=L,pre指向尾结点,释放它
  61. }
  62. bool ListEmpty(DLinkNode *L) //判线性表是否为空表
  63. {
  64. return(L->next==L);
  65. }
  66. int ListLength(DLinkNode *L) //求线性表的长度
  67. {
  68. DLinkNode *p=L;
  69. int i=0;
  70. while (p->next!=L)
  71. {
  72. i++;
  73. p=p->next;
  74. }
  75. return(i); //循环结束,p指向尾结点,其序号i为结点个数
  76. }
  77. void DispList(DLinkNode *L) //输出线性表
  78. {
  79. DLinkNode *p=L->next;
  80. while (p!=L)
  81. {
  82. printf("%c ",p->data);
  83. p=p->next;
  84. }
  85. printf("\n");
  86. }
  87. bool GetElem(DLinkNode *L,int i,ElemType &e) //求线性表中第i个元素值
  88. {
  89. int j=1;
  90. DLinkNode *p=L->next;
  91. if (i<=0 || L->next==L)
  92. return false; //i错误或者L为空表返回假
  93. if (i==1) //i=1作为特殊情况处理
  94. {
  95. e=L->next->data;
  96. return true;
  97. }
  98. else //i不为1时
  99. {
  100. while (j<=i-1 && p!=L) //查找第i个结点p
  101. {
  102. j++;
  103. p=p->next;
  104. }
  105. if (p==L) //没有找到第i个节,返回假
  106. return false;
  107. else //找到了第i个节,返回真
  108. {
  109. e=p->data;
  110. return true;
  111. }
  112. }
  113. }
  114. int LocateElem(DLinkNode *L,ElemType e) //查找第一个值域为e的元素序号
  115. {
  116. int i=1;
  117. DLinkNode *p=L->next;
  118. while (p!=NULL && p->data!=e)
  119. {
  120. i++;
  121. p=p->next;
  122. }
  123. if (p==NULL) //不存在值为e的结点,返回0
  124. return(0);
  125. else //存在值为e的结点,返回其逻辑序号i
  126. return(i);
  127. }
  128. bool ListInsert(DLinkNode *&L,int i,ElemType e) //插入第i个元素
  129. {
  130. int j=1;
  131. DLinkNode *p=L,*s;
  132. if (i<=0) return false; //i错误返回假
  133. if (p->next==L) //原双链表为空表时
  134. {
  135. s=(DLinkNode *)malloc(sizeof(DLinkNode)); //创建新结点s
  136. s->data=e;
  137. p->next=s;s->next=p;
  138. p->prior=s;s->prior=p;
  139. return true;
  140. }
  141. else if (i==1) //L不为空,i=1作为特殊情况处理
  142. {
  143. s=(DLinkNode *)malloc(sizeof(DLinkNode)); //创建新结点s
  144. s->data=e;
  145. s->next=p->next;p->next=s; //将结点s插入到结点p之后
  146. s->next->prior=s;s->prior=p;
  147. return true;
  148. }
  149. else //i不为1时
  150. {
  151. p=L->next;
  152. while (j<=i-2 && p!=L) //查找第i-1个结点p
  153. { j++;
  154. p=p->next;
  155. }
  156. if (p==L) //未找到第i-1个结点
  157. return false;
  158. else //找到第i-1个结点*p
  159. {
  160. s=(DLinkNode *)malloc(sizeof(DLinkNode)); //创建新结点s
  161. s->data=e;
  162. s->next=p->next; //将结点s插入到结点p之后
  163. if (p->next!=NULL) p->next->prior=s;
  164. s->prior=p;
  165. p->next=s;
  166. return true;
  167. }
  168. }
  169. }
  170. bool ListDelete(DLinkNode *&L,int i,ElemType &e) //删除第i个元素
  171. {
  172. int j=1;
  173. DLinkNode *p=L,*q;
  174. if (i<=0 || L->next==L)
  175. return false; //i错误或者为空表返回假
  176. if (i==1) //i==1作为特殊情况处理
  177. {
  178. q=L->next; //删除第1个结点
  179. e=q->data;
  180. L->next=q->next;
  181. q->next->prior=L;
  182. free(q);
  183. return true;
  184. }
  185. else //i不为1时
  186. {
  187. p=L->next;
  188. while (j<=i-2 && p!=NULL) //查找到第i-1个结点p
  189. {
  190. j++;
  191. p=p->next;
  192. }
  193. if (p==NULL) //未找到第i-1个结点
  194. return false;
  195. else //找到第i-1个结点p
  196. {
  197. q=p->next; //q指向要删除的结点
  198. if (q==NULL) return 0; //不存在第i个结点
  199. e=q->data;
  200. p->next=q->next; //从单链表中删除q结点
  201. if (p->next!=NULL) p->next->prior=p;
  202. free(q); //释放q结点
  203. return true;
  204. }
  205. }
  206. }
复制代码

6、一些常见算法的代码实现

【1】删除[x,y]区间内的值

  1. #include "sqlist_int.cpp"
  2. //一种更高效的算法删除[x,y]区间内的值(即把不在此区间内的值放在一个新建的顺序表中)
  3. void fun(SqList *&L,ElemType x,ElemType y)
  4. { int k=0; //新建的顺序表的下标变量
  5. for (int i=0;i<L->length;i++)
  6. if (!(L->data[i]>=x && L->data[i]<=y))
  7. L->data[k++]=L->data[i];
  8. L->length=k;
  9. }
  10. int main()
  11. {
  12. SqList *L;
  13. ElemType a[]={-1,-9,0,8,-7,11,5,-6};
  14. CreateList(L,a,8);
  15. printf("L:");DispList(L);
  16. printf("执行删除运算\n");
  17. fun(L,-6,5);
  18. printf("L:");DispList(L);
  19. DestroyList(L);
  20. return 1;
  21. }
复制代码

→代码执行结果如下:

 【2】使顺序表内所有小于0的值移到大于或等于0的值前面 

  1. #include "sqlist.cpp"
  2. //用高效的算法使顺序表内所有小于0的值移到大于或等于0的值前面
  3. void move2(SqList *&L) //快速排序的思想
  4. { int i=0,j=L->length-1;
  5. ElemType pivot=L->data[0]; //以data[0]为基准
  6. while (i<j) //从顺序表两端交替向中间扫描,直至i=j为止
  7. { while (j>i && L->data[j]>=0)
  8. j--; //从右向左扫描,找一个小于等于pivot的data[j]
  9. L->data[i]=L->data[j]; //找到这样的data[j],放入data[i]处
  10. while (i<j && L->data[i]<0)
  11. i++; //从左向右扫描,找一个大于pivot的记录data[i]
  12. L->data[j]=L->data[i]; //找到这样的data[i],放入data[j]处
  13. }
  14. L->data[i]=pivot; //最后将基准归位
  15. }
  16. int main()
  17. {
  18. SqList *L;
  19. ElemType a[]={-1,-9,0,8,-7,0,5,-6};
  20. CreateList(L,a,8);
  21. printf("L:");DispList(L);
  22. printf("执行移动运算\n");
  23. move2(L);
  24. printf("L:");DispList(L);
  25. DestroyList(L);
  26. return 1;
  27. }
复制代码

【3】找到下标为n/2的元素 

  1. #include "linklist.cpp"
  2. //找到下标为n/2的元素
  3. ElemType Midnode(LinkNode *L) //此算法采用双指针法,通过移动不同的步数最终找到中间的元素位置
  4. { LinkNode *q,*p;
  5. for (q=p=L->next; p->next!=NULL && p->next->next!=NULL; q=q->next,p=p->next->next)
  6. ;
  7. return q->data;
  8. }
  9. int main()
  10. {
  11. LinkNode *L;
  12. ElemType a[]="12345678";
  13. int n=(sizeof(a)-1)/sizeof(ElemType);
  14. CreateListR(L,a,n); //创建表
  15. printf("输出顺序表L:\n");
  16. DispList(L);
  17. printf("中间元素为:%c\n", Midnode(L));
  18. DestroyList(L);
  19. return 1;
  20. }
复制代码

 【4】循环单链表实现两个单链表的合并 

  1. #include "clinklist.cpp"
  2. //循环单链表实现两个单链表的合并
  3. void Merge(LinkNode *ha, LinkNode *hb, LinkNode *&hc)
  4. { LinkNode *p;
  5. hc=ha;
  6. for (p=ha;p->next!=ha;p=p->next)
  7. ; //找到ha的尾结点p
  8. p->next=hb->next; //将结点p的next指向hb的首结点
  9. for ( ;p->next!=hb;p=p->next)
  10. ; //找到hb的尾结点p
  11. p->next=hc; //构成循环单链表
  12. free(hb); //释放hb单链表的头结点
  13. }
  14. int main()
  15. {
  16. LinkNode *ha,*hb,*hc;
  17. ElemType a[]={1,2,3,4,5},b[]={6,7,8,9,10};
  18. int n=5;
  19. CreateListR(ha,a,n);
  20. CreateListR(hb,b,n);
  21. printf("ha:");DispList(ha);
  22. printf("hb:");DispList(hb);
  23. Merge(ha,hb,hc);
  24. printf("hc:");DispList(hc);
  25. printf("\n释放链表hc。");
  26. DestroyList(hc);
  27. return 1;
  28. }
复制代码

【5】将L中所有数据结点按x进行划分,尾插法新建L表  

  1. #include "linklist.cpp" //包含单链表的基本运算算法
  2. void Split(LinkNode *&L,ElemType x) //将L中所有数据结点按x进行划分,尾插法新建L表
  3. {
  4. LinkNode *p=L->next,*t,*r;
  5. L->next=NULL; //L变为空链表
  6. r=L;
  7. while (p!=NULL) //等价于while (p)
  8. {
  9. if (p->data<x) //若p结点值小于x,将其插入在开头
  10. {
  11. t=p->next; //t帮p临时站岗
  12. p->next=L->next;//将结点p插入到L的开头
  13. L->next=p;
  14. if (p->next==NULL) //若p结点是第一个在开头插入的结点
  15. r=p; //则它是尾结点
  16. p=t; //t还给p
  17. }
  18. else //若p结点值大于或等于x,将其插入到末尾
  19. {
  20. r->next=p;
  21. r=p;
  22. p=p->next;
  23. }
  24. }
  25. r->next=NULL;
  26. }
  27. int main()
  28. {
  29. LinkNode *L;
  30. ElemType a[]="adbacbchfdeg";
  31. int n=(sizeof(a)-1)/sizeof(ElemType);
  32. CreateListR(L,a,n);
  33. printf("L:"); DispList(L);
  34. ElemType x='d';
  35. printf("以%c进行划分\n",x);
  36. Split(L,x);
  37. printf("L:"); DispList(L);
  38. DestroyList(L);
  39. return 1;
  40. }
复制代码

这是第一章线性表的全部内容了,因为很详细,篇幅较长,下一章的栈和队列在下篇博客里,需要学习的朋友可以直接去点击→第二章 栈和队列

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Honkers

荣誉红客

关注
  • 4012
    主题
  • 36
    粉丝
  • 0
    关注
这家伙很懒,什么都没留下!

中国红客联盟公众号

联系站长QQ:5520533

admin@chnhonker.com
Copyright © 2001-2025 Discuz Team. Powered by Discuz! X3.5 ( 粤ICP备13060014号 )|天天打卡 本站已运行