1.3 链表

1.3.1 头插法建立单链表

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. typedef char datatype;
  4. typedef struct node{
  5. datatype data;
  6. struct node *next;
  7. } listnode;
  8. typedef listnode *linklist;
  9. listnode *p;
  10. linklist createlist(void)
  11. {
  12. char ch;
  13. linklist head;
  14. listnode *p;
  15. head=NULL;/*初始化为空*/
  16. ch=getchar( );
  17. while (ch!='\n'){
  18. p=(listnode*)malloc(sizeof(listnode));/*分配空间*/
  19. p->data=ch;/*数据域赋值*/
  20. p->next=head;/*指定后继指针*/
  21. head=p;/*head指针指定到新插入的结点上*/
  22. ch=getchar( );
  23. }
  24. return (head);
  25. }
  26. int main()
  27. {
  28. linklist newlist=createlist();
  29. do
  30. {
  31. printf("%c\n",newlist->data);
  32. newlist=newlist->next;
  33. }while(newlist!=NULL);
  34. printf("\n");
  35. return 0;
  36. }

运行结果

1.3.2 限制链表长度建立单链表

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #define N 4
  4. typedef char datatype;
  5. typedef struct node{
  6. datatype data;
  7. struct node *next;
  8. } listnode;
  9. typedef listnode *linklist;
  10. listnode *p;
  11. linklist createlist(int n)
  12. {
  13. int i;
  14. linklist head;
  15. listnode *p;
  16. head=NULL;
  17. for(i=n;i>0;--i)/*指定长度为n,插入次数受限制*/
  18. {
  19. p=(listnode*)malloc(sizeof(listnode));
  20. scanf("%c",&p->data);
  21. p->next=head;
  22. head=p;
  23. }
  24. return(head);
  25. }
  26. int main()
  27. {
  28. linklist newlist=createlist(N);
  29. do
  30. {
  31. printf("%c",newlist->data);
  32. newlist=newlist->next;
  33. }while(newlist!=NULL);
  34. printf("\n");
  35. return 0;
  36. }

运行结果

1.3.3 尾插法建立单链表

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #define N 4
  4. typedef char datatype;
  5. typedef struct node{
  6. datatype data;
  7. struct node *next;
  8. } listnode;
  9. typedef listnode *linklist;
  10. listnode *p;
  11. linklist creater()
  12. {
  13. char ch;
  14. linklist head;
  15. listnode *p,*r;
  16. head=NULL;
  17. r=NULL;/*r为尾指针*/
  18. while((ch=getchar())!='\n'){
  19. p=(listnode *)malloc(sizeof(listnode));
  20. p->data=ch;
  21. if(head==NULL)
  22. head=p;/*head 指向第一个插入结点*/
  23. else
  24. r->next=p;/*插入到链表尾部*/
  25. r=p;/*r指向最新结点,即最后结点*/
  26. }
  27. if (r!=NULL)
  28. r->next=NULL;/*链表尾部结点的后继指针指定为空*/
  29. return(head);
  30. }
  31. int main()
  32. {
  33. linklist newlist=creater();
  34. do
  35. {
  36. printf("%c",newlist->data);
  37. newlist=newlist->next;
  38. }while(newlist!=NULL);
  39. printf("\n");
  40. return 0;
  41. }

运行结果

1.3.4 按序号查找单链表

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. typedef char datatype;
  4. typedef struct node {
  5. datatype data;
  6. struct node *next;
  7. } listnode;
  8. typedef listnode *linklist;
  9. listnode *p;
  10. linklist createlist(void) {
  11. char ch;
  12. linklist head;
  13. listnode *p;
  14. head = NULL;/*初始化为空*/
  15. ch = getchar();
  16. while (ch != '\n') {
  17. p = (listnode *) malloc(sizeof(listnode));/*分配空间*/
  18. p->data = ch;/*数据域赋值*/
  19. p->next = head;/*指定后继指针*/
  20. head = p;/*head指针指定到新插入的结点上*/
  21. ch = getchar();
  22. }
  23. return (head);
  24. }
  25. listnode *getnode(linklist head, int i) {
  26. int j;
  27. listnode *p;
  28. p = head;
  29. j = 0;
  30. while (p->next && j < i) {/*遍历第i个结点前的所有结点*/
  31. p = p->next;
  32. j++;
  33. }
  34. if (i == j) {
  35. printf("%c\n", p->data);
  36. return p;
  37. } else
  38. return NULL;
  39. }
  40. int main() {
  41. linklist list;
  42. listnode *node;
  43. int i = 0;
  44. list = createlist();
  45. node = getnode(list, i);
  46. return 0;
  47. }

运行结果

1.3.5 按值查找单链表

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. typedef char datatype;
  4. typedef struct node {
  5. datatype data;
  6. struct node *next;
  7. } listnode;
  8. typedef listnode *linklist;
  9. listnode *p;
  10. linklist createlist(void) {
  11. char ch;
  12. linklist head;
  13. listnode *p;
  14. head = NULL;/*初始化为空*/
  15. ch = getchar();
  16. while (ch != '\n') {
  17. p = (listnode *) malloc(sizeof(listnode));/*分配空间*/
  18. p->data = ch;/*数据域赋值*/
  19. p->next = head;/*指定后继指针*/
  20. head = p;/*head指针指定到新插入的结点上*/
  21. ch = getchar();
  22. }
  23. return (head);
  24. }
  25. listnode *locatenode(linklist head, char key) {
  26. listnode *p = head;
  27. while (p->next && p->data != key)
  28. p = p->next;
  29. if (p != NULL)
  30. printf("%c\n", p->data);
  31. return p;
  32. }
  33. int main() {
  34. linklist list;
  35. listnode *node;
  36. char key = 'c';
  37. list = createlist();
  38. node = locatenode(list, key);
  39. return 0;
  40. }

运行结果

1.3.6 链表的插入

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. typedef char datatype;
  4. typedef struct node {
  5. datatype data;
  6. struct node *next;
  7. } listnode;
  8. typedef listnode *linklist;
  9. listnode *p;
  10. linklist createlist(void) {
  11. char ch;
  12. linklist head;
  13. listnode *p;
  14. head = NULL;/*初始化为空*/
  15. ch = getchar();
  16. while (ch != '\n') {
  17. p = (listnode *) malloc(sizeof(listnode));/*分配空间*/
  18. p->data = ch;/*数据域赋值*/
  19. p->next = head;/*指定后继指针*/
  20. head = p;/*head指针指定到新插入的结点上*/
  21. ch = getchar();
  22. }
  23. return (head);
  24. }
  25. void insertnode(linklist head, char x, int i) {
  26. int j = 0;
  27. listnode *p, *s;
  28. p = head;
  29. while (p && j < i - 1) {
  30. p = p->next;
  31. ++j;
  32. }
  33. if (!p || j > i - 1)
  34. exit(1);
  35. s = (linklist) malloc(sizeof(listnode));
  36. s->data = x;
  37. s->next = p->next;
  38. p->next = s;
  39. }
  40. int main() {
  41. linklist list;
  42. int i = 1;
  43. char x = 'c';
  44. list = createlist();
  45. insertnode(list, x, i);
  46. do {
  47. printf("%c", list->data);
  48. list = list->next;
  49. } while (list != NULL);
  50. printf("\n");
  51. return 0;
  52. }

运行结果

1.3.7 链表的删除

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. typedef char datatype;
  4. typedef struct node{
  5. datatype data;
  6. struct node *next;
  7. } listnode;
  8. typedef listnode *linklist;
  9. listnode *p;
  10. linklist createlist(void)
  11. {
  12. char ch;
  13. linklist head;
  14. listnode *p;
  15. head=NULL;/*初始化为空*/
  16. ch=getchar( );
  17. while (ch!='\n'){
  18. p=(listnode*)malloc(sizeof(listnode));/*分配空间*/
  19. p->data=ch;/*数据域赋值*/
  20. p->next=head;/*指定后继指针*/
  21. head=p;/*head指针指定到新插入的结点上*/
  22. ch=getchar( );
  23. }
  24. return (head);
  25. }
  26. void deletelist(linklist head,int i)
  27. {
  28. int j=0;
  29. listnode * p,*r;
  30. p=head;
  31. while(p&&j<i-1){
  32. p=p->next;
  33. ++j;
  34. }
  35. if(!p->next||j>i-1)
  36. exit(1);
  37. r=p->next;
  38. p->next=r->next;
  39. free(r) ;
  40. }
  41. int main()
  42. {
  43. linklist list;
  44. int i=1;
  45. list=createlist();
  46. deletelist(list,i);
  47. do
  48. {
  49. printf("%c",list->data);
  50. list=list->next;
  51. }while(list!=NULL);
  52. printf("\n");
  53. return 0;
  54. }

1.3.8 归并两个单链表

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. typedef char datatype;
  4. typedef struct node {
  5. datatype data;
  6. struct node *next;
  7. } listnode;
  8. typedef listnode *linklist;
  9. listnode *p;
  10. linklist createlist(void) {
  11. char ch;
  12. linklist head;
  13. listnode *p;
  14. head = NULL;/*初始化为空*/
  15. ch = getchar();
  16. while (ch != '\n') {
  17. p = (listnode *) malloc(sizeof(listnode));/*分配空间*/
  18. p->data = ch;/*数据域赋值*/
  19. p->next = head;/*指定后继指针*/
  20. head = p;/*head指针指定到新插入的结点上*/
  21. ch = getchar();
  22. }
  23. return (head);
  24. }
  25. linklist concatenate(linklist list1, linklist list2) {
  26. listnode *temp;
  27. if (list1 == NULL)
  28. return list2;
  29. else {
  30. if (list2 != NULL) {
  31. for (temp = list1; temp->next; temp = temp->next); /*遍历到list1的末尾*/
  32. temp->next = list2;/*将list2链接到list1末尾*/
  33. }
  34. }
  35. return list1;
  36. }
  37. int main() {
  38. linklist list1, list2, list3;
  39. list1 = createlist();
  40. list2 = createlist();
  41. list3 = concatenate(list1, list2);
  42. do {
  43. printf("%c", list3->data);
  44. list3 = list3->next;
  45. } while (list3 != NULL);
  46. printf("\n");
  47. return 0;
  48. }

1.3.9 初始化单循环链表

  1. #include<stdio.h> /* EOF(=^Z或F6),NULL */
  2. #include<stdlib.h>
  3. #include<math.h> /* floor(),ceil(),abs() */
  4. #define TRUE 1
  5. #define FALSE 0
  6. #define OK 1
  7. #define ERROR 0
  8. #define OVERFLOW -1
  9. typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等 */
  10. typedef int ElemType;
  11. /* c2-2.h 线性表的单链表存储结构 */
  12. struct LNode {
  13. ElemType data;
  14. struct LNode *next;
  15. };
  16. typedef struct LNode *LinkList; /* 另一种定义LinkList的方法 */
  17. Status InitList_CL(LinkList *L) { /* 操作结果:构造一个空的线性表L */
  18. *L = (LinkList) malloc(sizeof(struct LNode)); /* 产生头结点,并使L指向此头结点 */
  19. if (!*L) /* 存储分配失败 */
  20. exit(OVERFLOW);
  21. (*L)->next = *L; /* 指针域指向头结点 */
  22. return OK;
  23. }
  24. Status ListEmpty_CL(LinkList L) { /* 初始条件:线性表L已存在。操作结果:若L为空表,则返回TRUE,否则返回FALSE */
  25. if (L->next == L) /* 空 */
  26. return TRUE;
  27. else
  28. return FALSE;
  29. }
  30. int ListLength_CL(LinkList L) { /* 初始条件:L已存在。操作结果:返回L中数据元素个数 */
  31. int i = 0;
  32. LinkList p = L->next; /* p指向头结点 */
  33. while (p != L) /* 没到表尾 */
  34. {
  35. i++;
  36. p = p->next;
  37. }
  38. return i;
  39. }
  40. Status GetElem_CL(LinkList L, int i, ElemType *e) { /* 当第i个元素存在时,其值赋给e并返回OK,否则返回ERROR */
  41. int j = 1; /* 初始化,j为计数器 */
  42. LinkList p = L->next->next; /* p指向第一个结点 */
  43. if (i <= 0 || i > ListLength_CL(L)) /* 第i个元素不存在 */
  44. return ERROR;
  45. while (j < i) { /* 顺指针向后查找,直到p指向第i个元素 */
  46. p = p->next;
  47. j++;
  48. }
  49. *e = p->data; /* 取第i个元素 */
  50. return OK;
  51. }
  52. Status ListInsert_CL(LinkList *L, int i, ElemType e) /* 改变L */
  53. { /* 在L的第i个位置之前插入元素e */
  54. LinkList p = (*L)->next, s; /* p指向头结点 */
  55. int j = 0;
  56. if (i <= 0 || i > ListLength_CL(*L) + 1) /* 无法在第i个元素之前插入 */
  57. return ERROR;
  58. while (j < i - 1) /* 寻找第i-1个结点 */
  59. {
  60. p = p->next;
  61. j++;
  62. }
  63. s = (LinkList) malloc(sizeof(struct LNode)); /* 生成新结点 */
  64. s->data = e; /* 插入L中 */
  65. s->next = p->next;
  66. p->next = s;
  67. if (p == *L) /* 改变尾结点 */
  68. *L = s;
  69. return OK;
  70. }
  71. Status ListTraverse_CL(LinkList L, void(*vi)(ElemType)) { /* 初始条件:L已存在。操作结果:依次对L的每个数据元素调用函数vi()。一旦vi()失败,则操作失败 */
  72. LinkList p = L->next->next;
  73. while (p != L->next) {
  74. vi(p->data);
  75. p = p->next;
  76. }
  77. printf("\n");
  78. return OK;
  79. }
  80. void visit(ElemType c) {
  81. printf("%d ", c);
  82. }
  83. int main() {
  84. LinkList L;
  85. ElemType e;
  86. int j;
  87. Status i;
  88. i = InitList_CL(&L); /* 初始化单循环链表L */
  89. printf("初始化单循环链表L i=%d (1:初始化成功)\n", i);
  90. i = ListEmpty_CL(L);
  91. printf("L是否空 i=%d(1:空 0:否)\n", i);
  92. ListInsert_CL(&L, 1, 3); /* 在L中依次插入3,5 */
  93. ListInsert_CL(&L, 2, 5);
  94. i = GetElem_CL(L, 1, &e);
  95. j = ListLength_CL(L);
  96. printf("L中数据元素个数=%d,第1个元素的值为%d。\n", j, e);
  97. printf("L中的数据元素依次为:");
  98. ListTraverse_CL(L, visit);
  99. return 0;
  100. }

运行结果

1.3.10 查询元素的前驱和后继

  1. #include<stdio.h> /* EOF(=^Z或F6),NULL */
  2. #include<stdlib.h>
  3. #include<math.h> /* floor(),ceil(),abs() */
  4. #define TRUE 1
  5. #define FALSE 0
  6. #define OK 1
  7. #define ERROR 0
  8. #define OVERFLOW -1
  9. typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等 */
  10. typedef int ElemType;
  11. struct LNode {
  12. ElemType data;
  13. struct LNode *next;
  14. };
  15. typedef struct LNode *LinkList; /* 另一种定义LinkList的方法 */
  16. Status InitList_CL(LinkList *L) { /* 操作结果:构造一个空的线性表L */
  17. *L = (LinkList) malloc(sizeof(struct LNode)); /* 产生头结点,并使L指向此头结点 */
  18. if (!*L) /* 存储分配失败 */
  19. exit(OVERFLOW);
  20. (*L)->next = *L; /* 指针域指向头结点 */
  21. return OK;
  22. }
  23. Status ListEmpty_CL(LinkList L) { /* 初始条件:线性表L已存在。操作结果:若L为空表,则返回TRUE,否则返回FALSE */
  24. if (L->next == L) /* 空 */
  25. return TRUE;
  26. else
  27. return FALSE;
  28. }
  29. int ListLength_CL(LinkList L) { /* 初始条件:L已存在。操作结果:返回L中数据元素个数 */
  30. int i = 0;
  31. LinkList p = L->next; /* p指向头结点 */
  32. while (p != L) /* 没到表尾 */
  33. {
  34. i++;
  35. p = p->next;
  36. }
  37. return i;
  38. }
  39. Status GetElem_CL(LinkList L, int i, ElemType *e) { /* 当第i个元素存在时,其值赋给e并返回OK,否则返回ERROR */
  40. int j = 1; /* 初始化,j为计数器 */
  41. LinkList p = L->next->next; /* p指向第一个结点 */
  42. if (i <= 0 || i > ListLength_CL(L)) /* 第i个元素不存在 */
  43. return ERROR;
  44. while (j < i) { /* 顺指针向后查找,直到p指向第i个元素 */
  45. p = p->next;
  46. j++;
  47. }
  48. *e = p->data; /* 取第i个元素 */
  49. return OK;
  50. }
  51. Status ListInsert_CL(LinkList *L, int i, ElemType e) /* 改变L */
  52. { /* 在L的第i个位置之前插入元素e */
  53. LinkList p = (*L)->next, s; /* p指向头结点 */
  54. int j = 0;
  55. if (i <= 0 || i > ListLength_CL(*L) + 1) /* 无法在第i个元素之前插入 */
  56. return ERROR;
  57. while (j < i - 1) /* 寻找第i-1个结点 */
  58. {
  59. p = p->next;
  60. j++;
  61. }
  62. s = (LinkList) malloc(sizeof(struct LNode)); /* 生成新结点 */
  63. s->data = e; /* 插入L中 */
  64. s->next = p->next;
  65. p->next = s;
  66. if (p == *L) /* 改变尾结点 */
  67. *L = s;
  68. return OK;
  69. }
  70. Status PriorElem_CL(LinkList L, ElemType cur_e, ElemType *pre_e) { /* 初始条件:线性表L已存在 */
  71. /* 操作结果:若cur_e是L的数据元素,且不是第一个,则用pre_e返回它的前驱, */
  72. /* 否则操作失败,pre_e无定义 */
  73. LinkList q, p = L->next->next; /* p指向第一个结点 */
  74. q = p->next;
  75. while (q != L->next) /* p没到表尾 */
  76. {
  77. if (q->data == cur_e) {
  78. *pre_e = p->data;
  79. return TRUE;
  80. }
  81. p = q;
  82. q = q->next;
  83. }
  84. return FALSE;
  85. }
  86. Status NextElem_CL(LinkList L, ElemType cur_e, ElemType *next_e) { /* 初始条件:线性表L已存在 */
  87. /* 操作结果:若cur_e是L的数据元素,且不是最后一个,则用next_e返回它的后继, */
  88. /* 否则操作失败,next_e无定义 */
  89. LinkList p = L->next->next; /* p指向第一个结点 */
  90. while (p != L) /* p没到表尾 */
  91. {
  92. if (p->data == cur_e) {
  93. *next_e = p->next->data;
  94. return TRUE;
  95. }
  96. p = p->next;
  97. }
  98. return FALSE;
  99. }
  100. void visit(ElemType c) {
  101. printf("%d ", c);
  102. }
  103. int main() {
  104. LinkList L;
  105. ElemType e;
  106. int j;
  107. Status i;
  108. i = InitList_CL(&L); /* 初始化单循环链表L */
  109. printf("初始化单循环链表L i=%d (1:初始化成功)\n", i);
  110. i = ListEmpty_CL(L);
  111. printf("L是否空 i=%d(1:空 0:否)\n", i);
  112. ListInsert_CL(&L, 1, 3); /* 在L中依次插入3,5 */
  113. ListInsert_CL(&L, 2, 5);
  114. printf("依次插入元素3和5\n");
  115. PriorElem_CL(L, 5, &e); /* 求元素5的前驱 */
  116. printf("5前面的元素的值为%d。\n", e);
  117. NextElem_CL(L, 3, &e); /* 求元素3的后继 */
  118. printf("3后面的元素的值为%d。\n", e);
  119. return 0;
  120. }

运行结果

1.3.11 单循环链表中元素的删除

  1. #include<stdio.h> /* EOF(=^Z或F6),NULL */
  2. #include<math.h> /* floor(),ceil(),abs() */
  3. #include<stdlib.h>
  4. /* 函数结果状态代码 */
  5. #define TRUE 1
  6. #define FALSE 0
  7. #define OK 1
  8. #define ERROR 0
  9. #define OVERFLOW 3
  10. typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等 */
  11. typedef int Boolean; /* Boolean是布尔类型,其值是TRUE或FALSE */
  12. typedef int ElemType;
  13. struct LNode {
  14. ElemType data;
  15. struct LNode *next;
  16. };
  17. typedef struct LNode *LinkList; /* 另一种定义LinkList的方法 */
  18. Status InitList_CL(LinkList *L) { /* 操作结果:构造一个空的线性表L */
  19. *L = (LinkList) malloc(sizeof(struct LNode)); /* 产生头结点,并使L指向此头结点 */
  20. if (!*L) /* 存储分配失败 */
  21. exit(OVERFLOW);
  22. (*L)->next = *L; /* 指针域指向头结点 */
  23. return OK;
  24. }
  25. int ListLength_CL(LinkList L) { /* 初始条件:L已存在。操作结果:返回L中数据元素个数 */
  26. int i = 0;
  27. LinkList p = L->next; /* p指向头结点 */
  28. while (p != L) /* 没到表尾 */
  29. {
  30. i++;
  31. p = p->next;
  32. }
  33. return i;
  34. }
  35. int LocateElem_CL(LinkList L, ElemType e, Status(*compare)(ElemType, ElemType)) { /* 初始条件:线性表L已存在,compare()是数据元素判定函数 */
  36. /* 操作结果:返回L中第1个与e满足关系compare()的数据元素的位序。 */
  37. /* 若这样的数据元素不存在,则返回值为0 */
  38. int i = 0;
  39. LinkList p = L->next->next; /* p指向第一个结点 */
  40. while (p != L->next) {
  41. i++;
  42. if (compare(p->data, e)) /* 满足关系 */
  43. return i;
  44. p = p->next;
  45. }
  46. return 0;
  47. }
  48. Status ListInsert_CL(LinkList *L, int i, ElemType e) /* 改变L */
  49. { /* 在L的第i个位置之前插入元素e */
  50. LinkList p = (*L)->next, s; /* p指向头结点 */
  51. int j = 0;
  52. if (i <= 0 || i > ListLength_CL(*L) + 1) /* 无法在第i个元素之前插入 */
  53. return ERROR;
  54. while (j < i - 1) /* 寻找第i-1个结点 */
  55. {
  56. p = p->next;
  57. j++;
  58. }
  59. s = (LinkList) malloc(sizeof(struct LNode)); /* 生成新结点 */
  60. s->data = e; /* 插入L中 */
  61. s->next = p->next;
  62. p->next = s;
  63. if (p == *L) /* 改变尾结点 */
  64. *L = s;
  65. return OK;
  66. }
  67. Status ListDelete_CL(LinkList *L, int i, ElemType *e) /* 改变L */
  68. { /* 删除L的第i个元素,并由e返回其值 */
  69. LinkList p = (*L)->next, q; /* p指向头结点 */
  70. int j = 0;
  71. if (i <= 0 || i > ListLength_CL(*L)) /* 第i个元素不存在 */
  72. return ERROR;
  73. while (j < i - 1) /* 寻找第i-1个结点 */
  74. {
  75. p = p->next;
  76. j++;
  77. }
  78. q = p->next; /* q指向待删除结点 */
  79. p->next = q->next;
  80. *e = q->data;
  81. if (*L == q) /* 删除的是表尾元素 */
  82. *L = p;
  83. free(q); /* 释放待删除结点 */
  84. return OK;
  85. }
  86. Status ListTraverse_CL(LinkList L, void(*vi)(ElemType)) { /* 初始条件:L已存在。操作结果:依次对L的每个数据元素调用函数vi()。一旦vi()失败,则操作失败 */
  87. LinkList p = L->next->next;
  88. while (p != L->next) {
  89. vi(p->data);
  90. p = p->next;
  91. }
  92. printf("\n");
  93. return OK;
  94. }
  95. Status compare(ElemType c1, ElemType c2) {
  96. if (c1 == c2)
  97. return TRUE;
  98. else
  99. return FALSE;
  100. }
  101. void visit(ElemType c) {
  102. printf("%d ", c);
  103. }
  104. int main() {
  105. LinkList L;
  106. ElemType e;
  107. int j;
  108. Status i;
  109. i = InitList_CL(&L); /* 初始化单循环链表L */
  110. printf("依次在单循环链表中插入3,5\n");
  111. ListInsert_CL(&L, 1, 3); /* 在L中依次插入3,5 */
  112. ListInsert_CL(&L, 2, 5);
  113. j = LocateElem_CL(L, 5, compare);
  114. if (j)
  115. printf("L的第%d个元素为5。\n", j);
  116. else
  117. printf("不存在值为5的元素\n");
  118. i = ListDelete_CL(&L, 2, &e);
  119. printf("删除L的第2个元素:\n");
  120. if (i) {
  121. printf("删除的元素值为%d,现在L中的数据元素依次为:", e);
  122. ListTraverse_CL(L, visit);
  123. } else
  124. printf("删除不成功!\n");
  125. return 0;
  126. }

运行结果

1.3.12 单循环链表的清除和销毁

  1. #include<stdio.h> /* EOF(=^Z或F6),NULL */
  2. #include<math.h> /* floor(),ceil(),abs() */
  3. #include<stdlib.h>
  4. /* 函数结果状态代码 */
  5. #define TRUE 1
  6. #define FALSE 0
  7. #define OK 1
  8. #define ERROR 0
  9. #define OVERFLOW 1
  10. typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等 */
  11. typedef int ElemType;
  12. struct LNode {
  13. ElemType data;
  14. struct LNode *next;
  15. };
  16. typedef struct LNode *LinkList; /* 另一种定义LinkList的方法 */
  17. Status InitList_CL(LinkList *L) { /* 操作结果:构造一个空的线性表L */
  18. *L = (LinkList) malloc(sizeof(struct LNode)); /* 产生头结点,并使L指向此头结点 */
  19. if (!*L) /* 存储分配失败 */
  20. exit(OVERFLOW);
  21. (*L)->next = *L; /* 指针域指向头结点 */
  22. return OK;
  23. }
  24. Status DestroyList_CL(LinkList *L) { /* 操作结果:销毁线性表L */
  25. LinkList q, p = (*L)->next; /* p指向头结点 */
  26. while (p != *L) /* 没到表尾 */
  27. {
  28. q = p->next;
  29. free(p);
  30. p = q;
  31. }
  32. free(*L);
  33. *L = NULL;
  34. return OK;
  35. }
  36. Status ClearList_CL(LinkList *L) /* 改变L */
  37. { /* 初始条件:线性表L已存在。操作结果:将L重置为空表 */
  38. LinkList p, q;
  39. *L = (*L)->next; /* L指向头结点 */
  40. p = (*L)->next; /* p指向第一个结点 */
  41. while (p != *L) /* 没到表尾 */
  42. {
  43. q = p->next;
  44. free(p);
  45. p = q;
  46. }
  47. (*L)->next = *L; /* 头结点指针域指向自身 */
  48. return OK;
  49. }
  50. Status ListEmpty_CL(LinkList L) { /* 初始条件:线性表L已存在。操作结果:若L为空表,则返回TRUE,否则返回FALSE */
  51. if (L->next == L) /* 空 */
  52. return TRUE;
  53. else
  54. return FALSE;
  55. }
  56. int ListLength_CL(LinkList L) { /* 初始条件:L已存在。操作结果:返回L中数据元素个数 */
  57. int i = 0;
  58. LinkList p = L->next; /* p指向头结点 */
  59. while (p != L) /* 没到表尾 */
  60. {
  61. i++;
  62. p = p->next;
  63. }
  64. return i;
  65. }
  66. Status ListInsert_CL(LinkList *L, int i, ElemType e) /* 改变L */
  67. { /* 在L的第i个位置之前插入元素e */
  68. LinkList p = (*L)->next, s; /* p指向头结点 */
  69. int j = 0;
  70. if (i <= 0 || i > ListLength_CL(*L) + 1) /* 无法在第i个元素之前插入 */
  71. return ERROR;
  72. while (j < i - 1) /* 寻找第i-1个结点 */
  73. {
  74. p = p->next;
  75. j++;
  76. }
  77. s = (LinkList) malloc(sizeof(struct LNode)); /* 生成新结点 */
  78. s->data = e; /* 插入L中 */
  79. s->next = p->next;
  80. p->next = s;
  81. if (p == *L) /* 改变尾结点 */
  82. *L = s;
  83. return OK;
  84. }
  85. Status compare(ElemType c1, ElemType c2) {
  86. if (c1 == c2)
  87. return TRUE;
  88. else
  89. return FALSE;
  90. }
  91. void visit(ElemType c) {
  92. printf("%d ", c);
  93. }
  94. int main() {
  95. LinkList L;
  96. ElemType e;
  97. int j;
  98. Status i;
  99. i = InitList_CL(&L); /* 初始化单循环链表L */
  100. printf("依次在单循环链表中插入3,5\n");
  101. ListInsert_CL(&L, 1, 3); /* 在L中依次插入3,5 */
  102. ListInsert_CL(&L, 2, 5);
  103. printf("清空L:%d(1: 成功)\n", ClearList_CL(&L));
  104. printf("清空L后,L是否空:%d(1:空 0:否)\n", ListEmpty_CL(L));
  105. printf("销毁L:%d(1: 成功)\n", DestroyList_CL(&L));
  106. return 0;
  107. }

运行结果

1.3.13 仅设表尾指针循环链表的合并

  1. #include<stdio.h> /* EOF(=^Z或F6),NULL */
  2. #include<math.h> /* floor(),ceil(),abs() */
  3. #include <stdlib.h>
  4. #define OVERFLOW 3
  5. #define TRUE 1
  6. #define FALSE 0
  7. #define OK 1
  8. #define ERROR 0
  9. typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等 */
  10. typedef int ElemType;
  11. struct LNode {
  12. ElemType data;
  13. struct LNode *next;
  14. };
  15. typedef struct LNode *LinkList; /* 另一种定义LinkList的方法 */
  16. Status InitList_CL(LinkList *L) { /* 操作结果:构造一个空的线性表L */
  17. *L = (LinkList) malloc(sizeof(struct LNode)); /* 产生头结点,并使L指向此头结点 */
  18. if (!*L) /* 存储分配失败 */
  19. exit(OVERFLOW);
  20. (*L)->next = *L; /* 指针域指向头结点 */
  21. return OK;
  22. }
  23. int ListLength_CL(LinkList L) { /* 初始条件:L已存在。操作结果:返回L中数据元素个数 */
  24. int i = 0;
  25. LinkList p = L->next; /* p指向头结点 */
  26. while (p != L) /* 没到表尾 */
  27. {
  28. i++;
  29. p = p->next;
  30. }
  31. return i;
  32. }
  33. Status ListInsert_CL(LinkList *L, int i, ElemType e) /* 改变L */
  34. { /* 在L的第i个位置之前插入元素e */
  35. LinkList p = (*L)->next, s; /* p指向头结点 */
  36. int j = 0;
  37. if (i <= 0 || i > ListLength_CL(*L) + 1) /* 无法在第i个元素之前插入 */
  38. return ERROR;
  39. while (j < i - 1) /* 寻找第i-1个结点 */
  40. {
  41. p = p->next;
  42. j++;
  43. }
  44. s = (LinkList) malloc(sizeof(struct LNode)); /* 生成新结点 */
  45. s->data = e; /* 插入L中 */
  46. s->next = p->next;
  47. p->next = s;
  48. if (p == *L) /* 改变尾结点 */
  49. *L = s;
  50. return OK;
  51. }
  52. Status ListTraverse_CL(LinkList L, void(*vi)(ElemType)) { /* 初始条件:L已存在。操作结果:依次对L的每个数据元素调用函数vi()。一旦vi()失败,则操作失败 */
  53. LinkList p = L->next->next;
  54. while (p != L->next) {
  55. vi(p->data);
  56. p = p->next;
  57. }
  58. printf("\n");
  59. return OK;
  60. }
  61. void MergeList_CL(LinkList *La, LinkList Lb) {
  62. LinkList p = Lb->next;
  63. Lb->next = (*La)->next;
  64. (*La)->next = p->next;
  65. free(p);
  66. *La = Lb;
  67. }
  68. void visit(ElemType c) {
  69. printf("%d ", c);
  70. }
  71. int main() {
  72. int n = 5, i;
  73. LinkList La, Lb;
  74. InitList_CL(&La);
  75. for (i = 1; i <= n; i++)
  76. ListInsert_CL(&La, i, i);
  77. printf("La="); /* 输出链表La的内容 */
  78. ListTraverse_CL(La, visit);
  79. InitList_CL(&Lb);
  80. for (i = 1; i <= n; i++)
  81. ListInsert_CL(&Lb, 1, i * 2);
  82. printf("Lb="); /* 输出链表Lb的内容 */
  83. ListTraverse_CL(Lb, visit);
  84. MergeList_CL(&La, Lb);
  85. printf("La+Lb="); /* 输出合并后的链表的内容 */
  86. ListTraverse_CL(La, visit);
  87. return 0;
  88. }

1.3.14 正序输出双向链表

  1. #include<stdio.h> /* EOF(=^Z或F6),NULL */
  2. #include<math.h> /* floor(),ceil(),abs() */
  3. #define TRUE 1
  4. #define FALSE 0
  5. #define OK 1
  6. #define ERROR 0
  7. #define OVERFLOW 3
  8. typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等 */
  9. typedef int ElemType;
  10. typedef struct DuLNode {
  11. ElemType data;
  12. struct DuLNode *prior, *next;
  13. } DuLNode, *DuLinkList;
  14. /* bo2-5.c 双链循环线性表(存储结构由c2-4.h定义)的基本操作(14个) */
  15. Status InitList(DuLinkList *L) { /* 产生空的双向循环链表L */
  16. *L = (DuLinkList) malloc(sizeof(DuLNode));
  17. if (*L) {
  18. (*L)->next = (*L)->prior = *L;
  19. return OK;
  20. } else
  21. return OVERFLOW;
  22. }
  23. int ListLength(DuLinkList L) { /* 初始条件:L已存在。操作结果:返回L中数据元素个数 */
  24. int i = 0;
  25. DuLinkList p = L->next; /* p指向第一个结点 */
  26. while (p != L) /* p没到表头 */
  27. {
  28. i++;
  29. p = p->next;
  30. }
  31. return i;
  32. }
  33. DuLinkList GetElemP(DuLinkList L, int i) /* 另加 */
  34. { /* 在双向链表L中返回第i个元素的位置指针*/
  35. int j;
  36. DuLinkList p = L;
  37. for (j = 1; j <= i; j++)
  38. p = p->next;
  39. return p;
  40. }
  41. Status ListInsert(DuLinkList L, int i, ElemType e) { /* 在带头结点的双链循环线性表L中第i个位置之前插入元素e,i的合法值为1≤i≤表长+1 */
  42. DuLinkList p, s;
  43. if (i < 1 || i > ListLength(L) + 1) /* i值不合法 */
  44. return ERROR;
  45. p = GetElemP(L, i - 1); /* 在L中确定第i-1个元素的位置指针p */
  46. if (!p) /* p=NULL,即第i-1个元素不存在 */
  47. return ERROR;
  48. s = (DuLinkList) malloc(sizeof(DuLNode));
  49. if (!s)
  50. return OVERFLOW;
  51. s->data = e; /* 在第i-1个元素之后插入 */
  52. s->prior = p;
  53. s->next = p->next;
  54. p->next->prior = s;
  55. p->next = s;
  56. return OK;
  57. }
  58. void ListTraverse(DuLinkList L, void(*visit)(ElemType)) { /* 由双链循环线性表L的头结点出发,正序对每个数据元素调用函数visit() */
  59. DuLinkList p = L->next; /* p指向头结点 */
  60. while (p != L) {
  61. visit(p->data);
  62. p = p->next;
  63. }
  64. printf("\n");
  65. }
  66. void vd(ElemType c) /* ListTraverse()调用的函数(类型一致) */
  67. {
  68. printf("%d ", c);
  69. }
  70. int main() {
  71. DuLinkList L;
  72. int i;
  73. InitList(&L);
  74. for (i = 1; i <= 5; i++)
  75. ListInsert(L, i, i); /* 在第i个结点之前插入i */
  76. printf("正序输出链表:");
  77. ListTraverse(L, vd); /* 正序输出 */
  78. return 0;
  79. }

1.3.15 逆向输出双向链表

  1. #include<stdio.h> /* EOF(=^Z或F6),NULL */
  2. #include<math.h> /* floor(),ceil(),abs() */
  3. #define TRUE 1
  4. #define FALSE 0
  5. #define OK 1
  6. #define ERROR 0
  7. #define OVERFLOW 3
  8. typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等 */
  9. typedef int ElemType;
  10. typedef struct DuLNode {
  11. ElemType data;
  12. struct DuLNode *prior, *next;
  13. } DuLNode, *DuLinkList;
  14. Status InitList(DuLinkList *L) { /* 产生空的双向循环链表L */
  15. *L = (DuLinkList) malloc(sizeof(DuLNode));
  16. if (*L) {
  17. (*L)->next = (*L)->prior = *L;
  18. return OK;
  19. } else
  20. return OVERFLOW;
  21. }
  22. int ListLength(DuLinkList L) { /* 初始条件:L已存在。操作结果:返回L中数据元素个数 */
  23. int i = 0;
  24. DuLinkList p = L->next; /* p指向第一个结点 */
  25. while (p != L) /* p没到表头 */
  26. {
  27. i++;
  28. p = p->next;
  29. }
  30. return i;
  31. }
  32. DuLinkList GetElemP(DuLinkList L, int i) /* 另加 */
  33. { /* 在双向链表L中返回第i个元素的位置指针*/
  34. int j;
  35. DuLinkList p = L;
  36. for (j = 1; j <= i; j++)
  37. p = p->next;
  38. return p;
  39. }
  40. Status ListInsert(DuLinkList L, int i, ElemType e) { /* 在带头结点的双链循环线性表L中第i个位置之前插入元素e,i的合法值为1≤i≤表长+1 */
  41. DuLinkList p, s;
  42. if (i < 1 || i > ListLength(L) + 1) /* i值不合法 */
  43. return ERROR;
  44. p = GetElemP(L, i - 1); /* 在L中确定第i-1个元素的位置指针p */
  45. if (!p) /* p=NULL,即第i-1个元素不存在 */
  46. return ERROR;
  47. s = (DuLinkList) malloc(sizeof(DuLNode));
  48. if (!s)
  49. return OVERFLOW;
  50. s->data = e; /* 在第i-1个元素之后插入 */
  51. s->prior = p;
  52. s->next = p->next;
  53. p->next->prior = s;
  54. p->next = s;
  55. return OK;
  56. }
  57. void ListTraverseBack(DuLinkList L, void(*visit)(ElemType)) { /* 由双链循环线性表L的头结点出发,逆序对每个数据元素调用函数visit()。另加 */
  58. DuLinkList p = L->prior; /* p指向尾结点 */
  59. while (p != L) {
  60. visit(p->data);
  61. p = p->prior;
  62. }
  63. printf("\n");
  64. }
  65. void vd(ElemType c) /* ListTraverse()调用的函数(类型一致) */
  66. {
  67. printf("%d ", c);
  68. }
  69. int main() {
  70. DuLinkList L;
  71. int i;
  72. InitList(&L);
  73. for (i = 1; i <= 5; i++)
  74. ListInsert(L, i, i); /* 在第i个结点之前插入i */
  75. printf("逆序输出链表:");
  76. ListTraverseBack(L, vd); /* 逆序输出 */
  77. }

运行结果

1.3.16 删除双向链表中的节点

  1. #include<stdio.h> /* EOF(=^Z或F6),NULL */
  2. #include<math.h> /* floor(),ceil(),abs() */
  3. #include<stdlib.h>
  4. #define OVERFLOW 3
  5. #define TRUE 1
  6. #define FALSE 0
  7. #define OK 1
  8. #define ERROR 0
  9. typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等 */
  10. typedef int ElemType;
  11. typedef struct DuLNode {
  12. ElemType data;
  13. struct DuLNode *prior, *next;
  14. } DuLNode, *DuLinkList;
  15. Status InitList(DuLinkList *L) { /* 产生空的双向循环链表L */
  16. *L = (DuLinkList) malloc(sizeof(DuLNode));
  17. if (*L) {
  18. (*L)->next = (*L)->prior = *L;
  19. return OK;
  20. } else
  21. return OVERFLOW;
  22. }
  23. int ListLength(DuLinkList L) { /* 初始条件:L已存在。操作结果:返回L中数据元素个数 */
  24. int i = 0;
  25. DuLinkList p = L->next; /* p指向第一个结点 */
  26. while (p != L) /* p没到表头 */
  27. {
  28. i++;
  29. p = p->next;
  30. }
  31. return i;
  32. }
  33. DuLinkList GetElemP(DuLinkList L, int i) /* 另加 */
  34. { /* 在双向链表L中返回第i个元素的位置指针*/
  35. int j;
  36. DuLinkList p = L;
  37. for (j = 1; j <= i; j++)
  38. p = p->next;
  39. return p;
  40. }
  41. Status ListInsert(DuLinkList L, int i, ElemType e) { /* 在带头结点的双链循环线性表L中第i个位置之前插入元素e,i的合法值为1≤i≤表长+1 */
  42. DuLinkList p, s;
  43. if (i < 1 || i > ListLength(L) + 1) /* i值不合法 */
  44. return ERROR;
  45. p = GetElemP(L, i - 1); /* 在L中确定第i-1个元素的位置指针p */
  46. if (!p) /* p=NULL,即第i-1个元素不存在 */
  47. return ERROR;
  48. s = (DuLinkList) malloc(sizeof(DuLNode));
  49. if (!s)
  50. return OVERFLOW;
  51. s->data = e; /* 在第i-1个元素之后插入 */
  52. s->prior = p;
  53. s->next = p->next;
  54. p->next->prior = s;
  55. p->next = s;
  56. return OK;
  57. }
  58. void ListTraverse(DuLinkList L, void(*visit)(ElemType)) { /* 由双链循环线性表L的头结点出发,正序对每个数据元素调用函数visit() */
  59. DuLinkList p = L->next; /* p指向头结点 */
  60. while (p != L) {
  61. visit(p->data);
  62. p = p->next;
  63. }
  64. printf("\n");
  65. }
  66. Status ListDelete(DuLinkList L, int i, ElemType *e) { /* 删除带头结点的双链循环线性表L的第i个元素,i的合法值为1≤i≤表长+1 */
  67. DuLinkList p;
  68. if (i < 1 || i > ListLength(L)) /* i值不合法 */
  69. return ERROR;
  70. p = GetElemP(L, i); /* 在L中确定第i个元素的位置指针p */
  71. if (!p) /* p=NULL,即第i个元素不存在 */
  72. return ERROR;
  73. *e = p->data;
  74. p->prior->next = p->next;
  75. p->next->prior = p->prior;
  76. free(p);
  77. return OK;
  78. }
  79. void vd(ElemType c) /* ListTraverse()调用的函数(类型一致) */
  80. {
  81. printf("%d ", c);
  82. }
  83. int main() {
  84. DuLinkList L;
  85. int i, n = 2;
  86. ElemType e;
  87. InitList(&L);
  88. printf("初始化链表依次输入1,2,3,4,5\n");
  89. for (i = 1; i <= 5; i++)
  90. ListInsert(L, i, i); /* 在第i个结点之前插入i */
  91. ListDelete(L, n, &e); /* 删除并释放第n个结点 */
  92. printf("删除第%d个结点,值为%d,其余结点为:", n, e);
  93. ListTraverse(L, vd); /* 正序输出 */
  94. }

运行结果

1.3.17 双向链表的元素个数

  1. #include<stdio.h> /* EOF(=^Z或F6),NULL */
  2. #include<math.h> /* floor(),ceil(),abs() */
  3. #define TRUE 1
  4. #define FALSE 0
  5. #define OK 1
  6. #define ERROR 0
  7. #define OVERFLOW 3
  8. typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等 */
  9. typedef int ElemType;
  10. typedef struct DuLNode {
  11. ElemType data;
  12. struct DuLNode *prior, *next;
  13. } DuLNode, *DuLinkList;
  14. Status InitList(DuLinkList *L) { /* 产生空的双向循环链表L */
  15. *L = (DuLinkList) malloc(sizeof(DuLNode));
  16. if (*L) {
  17. (*L)->next = (*L)->prior = *L;
  18. return OK;
  19. } else
  20. return OVERFLOW;
  21. }
  22. int ListLength(DuLinkList L) { /* 初始条件:L已存在。操作结果:返回L中数据元素个数 */
  23. int i = 0;
  24. DuLinkList p = L->next; /* p指向第一个结点 */
  25. while (p != L) /* p没到表头 */
  26. {
  27. i++;
  28. p = p->next;
  29. }
  30. return i;
  31. }
  32. DuLinkList GetElemP(DuLinkList L, int i) /* 另加 */
  33. { /* 在双向链表L中返回第i个元素的位置指针(算法2.18、2.19要调用的函数) */
  34. int j;
  35. DuLinkList p = L;
  36. for (j = 1; j <= i; j++)
  37. p = p->next;
  38. return p;
  39. }
  40. Status ListInsert(DuLinkList L, int i, ElemType e) /* 改进算法2.18 */
  41. { /* 在带头结点的双链循环线性表L中第i个位置之前插入元素e,i的合法值为1≤i≤表长+1 */
  42. DuLinkList p, s;
  43. if (i < 1 || i > ListLength(L) + 1) /* i值不合法 */
  44. return ERROR;
  45. p = GetElemP(L, i - 1); /* 在L中确定第i-1个元素的位置指针p */
  46. if (!p) /* p=NULL,即第i-1个元素不存在 */
  47. return ERROR;
  48. s = (DuLinkList) malloc(sizeof(DuLNode));
  49. if (!s)
  50. return OVERFLOW;
  51. s->data = e; /* 在第i-1个元素之后插入 */
  52. s->prior = p;
  53. s->next = p->next;
  54. p->next->prior = s;
  55. p->next = s;
  56. return OK;
  57. }
  58. void vd(ElemType c) /* ListTraverse()调用的函数(类型一致) */
  59. {
  60. printf("%d ", c);
  61. }
  62. int main() {
  63. DuLinkList L;
  64. int i, n = 2;
  65. ElemType e;
  66. InitList(&L);
  67. printf("初始化链表依次输入1,2,3,4,5\n");
  68. for (i = 1; i <= 5; i++)
  69. ListInsert(L, i, i); /* 在第i个结点之前插入i */
  70. printf("链表的元素个数为%d\n", ListLength(L));
  71. return 0;
  72. }

运行结果

1.3.18 判断双向链表是否为空

  1. #include<stdio.h> /* EOF(=^Z或F6),NULL */
  2. #include<math.h> /* floor(),ceil(),abs() */
  3. #define TRUE 1
  4. #define FALSE 0
  5. #define OK 1
  6. #define ERROR 0
  7. #define OVERFLOW 3
  8. typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等 */
  9. typedef int ElemType;
  10. typedef struct DuLNode {
  11. ElemType data;
  12. struct DuLNode *prior, *next;
  13. } DuLNode, *DuLinkList;
  14. Status InitList(DuLinkList *L) { /* 产生空的双向循环链表L */
  15. *L = (DuLinkList) malloc(sizeof(DuLNode));
  16. if (*L) {
  17. (*L)->next = (*L)->prior = *L;
  18. return OK;
  19. } else
  20. return OVERFLOW;
  21. }
  22. Status ClearList(DuLinkList L) /* 不改变L */
  23. { /* 初始条件:L已存在。操作结果:将L重置为空表 */
  24. DuLinkList q, p = L->next; /* p指向第一个结点 */
  25. while (p != L) /* p没到表头 */
  26. {
  27. q = p->next;
  28. free(p);
  29. p = q;
  30. }
  31. L->next = L->prior = L; /* 头结点的两个指针域均指向自身 */
  32. return OK;
  33. }
  34. int ListLength(DuLinkList L) { /* 初始条件:L已存在。操作结果:返回L中数据元素个数 */
  35. int i = 0;
  36. DuLinkList p = L->next; /* p指向第一个结点 */
  37. while (p != L) /* p没到表头 */
  38. {
  39. i++;
  40. p = p->next;
  41. }
  42. return i;
  43. }
  44. DuLinkList GetElemP(DuLinkList L, int i) /* 另加 */
  45. { /* 在双向链表L中返回第i个元素的位置指针(算法2.18、2.19要调用的函数) */
  46. int j;
  47. DuLinkList p = L;
  48. for (j = 1; j <= i; j++)
  49. p = p->next;
  50. return p;
  51. }
  52. Status ListInsert(DuLinkList L, int i, ElemType e) /* 改进算法2.18 */
  53. { /* 在带头结点的双链循环线性表L中第i个位置之前插入元素e,i的合法值为1≤i≤表长+1 */
  54. DuLinkList p, s;
  55. if (i < 1 || i > ListLength(L) + 1) /* i值不合法 */
  56. return ERROR;
  57. p = GetElemP(L, i - 1); /* 在L中确定第i-1个元素的位置指针p */
  58. if (!p) /* p=NULL,即第i-1个元素不存在 */
  59. return ERROR;
  60. s = (DuLinkList) malloc(sizeof(DuLNode));
  61. if (!s)
  62. return OVERFLOW;
  63. s->data = e; /* 在第i-1个元素之后插入 */
  64. s->prior = p;
  65. s->next = p->next;
  66. p->next->prior = s;
  67. p->next = s;
  68. return OK;
  69. }
  70. Status ListEmpty(DuLinkList L) { /* 初始条件:线性表L已存在。操作结果:若L为空表,则返回TRUE,否则返回FALSE */
  71. if (L->next == L && L->prior == L)
  72. return TRUE;
  73. else
  74. return FALSE;
  75. }
  76. void vd(ElemType c) /* ListTraverse()调用的函数(类型一致) */
  77. {
  78. printf("%d ", c);
  79. }
  80. int main() {
  81. DuLinkList L;
  82. int i, n = 2;
  83. ElemType e;
  84. InitList(&L);
  85. printf("初始化链表依次输入1,2,3,4,5\n");
  86. for (i = 1; i <= 5; i++)
  87. ListInsert(L, i, i); /* 在第i个结点之前插入i */
  88. printf("链表是否空:%d(1:是 0:否)\n", ListEmpty(L));
  89. ClearList(L); /* 清空链表 */
  90. printf("清空后,链表是否空:%d(1:是 0:否)\n", ListEmpty(L));
  91. return 0;
  92. }

运行结果

1.3.19 双向链表元素值的查询

  1. #include<stdio.h> /* EOF(=^Z或F6),NULL */
  2. #include<math.h> /* floor(),ceil(),abs() */
  3. #define TRUE 1
  4. #define FALSE 0
  5. #define OK 1
  6. #define ERROR 0
  7. #define OVERFLOW 3
  8. typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等 */
  9. typedef int ElemType;
  10. typedef struct DuLNode {
  11. ElemType data;
  12. struct DuLNode *prior, *next;
  13. } DuLNode, *DuLinkList;
  14. Status InitList(DuLinkList *L) { /* 产生空的双向循环链表L */
  15. *L = (DuLinkList) malloc(sizeof(DuLNode));
  16. if (*L) {
  17. (*L)->next = (*L)->prior = *L;
  18. return OK;
  19. } else
  20. return OVERFLOW;
  21. }
  22. Status ClearList(DuLinkList L) /* 不改变L */
  23. { /* 初始条件:L已存在。操作结果:将L重置为空表 */
  24. DuLinkList q, p = L->next; /* p指向第一个结点 */
  25. while (p != L) /* p没到表头 */
  26. {
  27. q = p->next;
  28. free(p);
  29. p = q;
  30. }
  31. L->next = L->prior = L; /* 头结点的两个指针域均指向自身 */
  32. return OK;
  33. }
  34. int ListLength(DuLinkList L) { /* 初始条件:L已存在。操作结果:返回L中数据元素个数 */
  35. int i = 0;
  36. DuLinkList p = L->next; /* p指向第一个结点 */
  37. while (p != L) /* p没到表头 */
  38. {
  39. i++;
  40. p = p->next;
  41. }
  42. return i;
  43. }
  44. Status GetElem(DuLinkList L, int i, ElemType *e) { /* 当第i个元素存在时,其值赋给e并返回OK,否则返回ERROR */
  45. int j = 1; /* j为计数器 */
  46. DuLinkList p = L->next; /* p指向第一个结点 */
  47. while (p != L && j < i) /* 顺指针向后查找,直到p指向第i个元素或p指向头结点 */
  48. {
  49. p = p->next;
  50. j++;
  51. }
  52. if (p == L || j > i) /* 第i个元素不存在 */
  53. return ERROR;
  54. *e = p->data; /* 取第i个元素 */
  55. return OK;
  56. }
  57. DuLinkList GetElemP(DuLinkList L, int i) /* 另加 */
  58. { /* 在双向链表L中返回第i个元素的位置指针*/
  59. int j;
  60. DuLinkList p = L;
  61. for (j = 1; j <= i; j++)
  62. p = p->next;
  63. return p;
  64. }
  65. Status ListInsert(DuLinkList L, int i, ElemType e) {
  66. DuLinkList p, s;
  67. if (i < 1 || i > ListLength(L) + 1) /* i值不合法 */
  68. return ERROR;
  69. p = GetElemP(L, i - 1); /* 在L中确定第i-1个元素的位置指针p */
  70. if (!p) /* p=NULL,即第i-1个元素不存在 */
  71. return ERROR;
  72. s = (DuLinkList) malloc(sizeof(DuLNode));
  73. if (!s)
  74. return OVERFLOW;
  75. s->data = e; /* 在第i-1个元素之后插入 */
  76. s->prior = p;
  77. s->next = p->next;
  78. p->next->prior = s;
  79. p->next = s;
  80. return OK;
  81. }
  82. Status ListEmpty(DuLinkList L) { /* 初始条件:线性表L已存在。操作结果:若L为空表,则返回TRUE,否则返回FALSE */
  83. if (L->next == L && L->prior == L)
  84. return TRUE;
  85. else
  86. return FALSE;
  87. }
  88. void vd(ElemType c) /* ListTraverse()调用的函数(类型一致) */
  89. {
  90. printf("%d ", c);
  91. }
  92. int main() {
  93. DuLinkList L;
  94. int i, n, j;
  95. ElemType e;
  96. InitList(&L);
  97. printf("初始化链表依次输入1,2,3,4,5\n");
  98. for (i = 1; i <= 5; i++)
  99. ListInsert(L, i, i); /* 在第i个结点之前插入i */
  100. n = 3;
  101. j = GetElem(L, n, &e); /* 将链表的第n个元素赋值给e */
  102. if (j)
  103. printf("链表的第%d个元素值为%d\n", n, e);
  104. else
  105. printf("不存在第%d个元素\n", n);
  106. }

运行结果

1.3.20 稀疏矩阵的建立

  1. #include "stdio.h"
  2. #include "stdlib.h"
  3. #define MAX_SIZE 50 /* 最大的稀疏矩阵 */
  4. typedef enum {head, entry} tagfield;
  5. struct entry_node {
  6. int row;
  7. int col;
  8. int value;
  9. };
  10. typedef struct Matrix {
  11. struct Matrix * down;
  12. struct Matrix * right;
  13. tagfield tag;
  14. union {
  15. struct Matrix * next;
  16. struct entry_node entry;
  17. } u;
  18. }matrix_node;
  19. typedef matrix_node * matrix_pointer;
  20. matrix_pointer hdnode [ MAX_SIZE ];
  21. matrix_pointer new_node(void)
  22. {
  23. matrix_pointer temp;
  24. temp = (matrix_pointer)malloc(sizeof(matrix_node));
  25. if (temp==NULL) {
  26. printf("The memory is full\n");
  27. exit(1);
  28. }
  29. return temp;
  30. }
  31. matrix_pointer Create(void)
  32. {
  33. int num_rows, num_cols, num_terms, num_heads, i,current_row;
  34. int col, value,row;
  35. matrix_pointer node,temp,last;
  36. printf("Enter the number of rows, columns and number of nonzero terms: ");
  37. scanf("%d%d%d",&num_rows,&num_cols,&num_terms);
  38. num_heads = (num_cols > num_rows) ? num_cols :num_rows;
  39. /* 建立新结点 */
  40. node = new_node();
  41. node->tag = entry;
  42. node->u.entry.row = num_rows;
  43. node->u.entry.col = num_cols;
  44. if ( !num_heads )
  45. node->right = node;
  46. else {
  47. for ( i = 0; i<num_heads; i++ ) {
  48. temp = new_node();
  49. hdnode[i] = temp;
  50. hdnode[i]->tag = head;
  51. hdnode[i]->right = temp;
  52. hdnode[i]->u.next = temp;
  53. }
  54. current_row = 0;
  55. last = hdnode[0];
  56. for ( i = 0; i < num_terms; i++ ) {
  57. printf("Enter row, column and value: ");
  58. scanf("%d%d%d",&row,&col,&value);
  59. if ( row > current_row ) {
  60. /* 转到row所在行去*/
  61. last->right = hdnode[current_row];
  62. current_row = row;
  63. last = hdnode[row];
  64. }
  65. temp = new_node();
  66. temp->tag = entry;
  67. temp->u.entry.row = row;
  68. temp->u.entry.col = col;
  69. temp->u.entry.value = value;
  70. last->right = temp;
  71. last = temp;
  72. /*链接到列结点上 */
  73. hdnode[col]->u.next->down = temp;
  74. hdnode[col]->u.next = temp;
  75. }
  76. /* 结束上一行结点 */
  77. last->right = hdnode[current_row];
  78. /*结束所有行结点*/
  79. for ( i=0; i<num_cols; i++ )
  80. hdnode[i]->u.next->down= hdnode[i];
  81. /*链接所有的头结点 */
  82. for ( i=0; i<num_heads-1; i++ )
  83. hdnode[i]->u.next = hdnode[i+1];
  84. hdnode[num_heads-1]->u.next = node;
  85. node->right = hdnode[0];
  86. }
  87. return node;
  88. }
  89. int main()
  90. {
  91. matrix_pointer matric=Create();
  92. return 0;
  93. }

运行结果

1.3.21 稀疏矩阵的删除

  1. #include <cstdlib>
  2. #include "stdio.h"
  3. #define MAX_SIZE 50 /* 最大的稀疏矩阵 */
  4. typedef enum {
  5. head, entry
  6. } tagfield;
  7. struct entry_node {
  8. int row;
  9. int col;
  10. int value;
  11. };
  12. typedef struct Matrix {
  13. struct Matrix *down;
  14. struct Matrix *right;
  15. tagfield tag;
  16. union {
  17. struct Matrix *next;
  18. struct entry_node entry;
  19. } u;
  20. } matrix_node;
  21. typedef matrix_node *matrix_pointer;
  22. matrix_pointer hdnode[MAX_SIZE];
  23. matrix_pointer new_node(void) {
  24. matrix_pointer temp;
  25. temp = (matrix_pointer) malloc(sizeof(matrix_node));
  26. if (temp == NULL) {
  27. printf("The memory is full\n");
  28. exit(1);
  29. }
  30. return temp;
  31. }
  32. matrix_pointer Create(void) {
  33. int num_rows, num_cols, num_terms, num_heads, i, current_row;
  34. int col, value, row;
  35. matrix_pointer node, temp, last;
  36. printf("Enter the number of rows, columns and number of nonzero terms: ");
  37. scanf("%d%d%d", &num_rows, &num_cols, &num_terms);
  38. num_heads = (num_cols > num_rows) ? num_cols : num_rows;
  39. /* 建立新结点 */
  40. node = new_node();
  41. node->tag = entry;
  42. node->u.entry.row = num_rows;
  43. node->u.entry.col = num_cols;
  44. if (!num_heads)
  45. node->right = node;
  46. else { /*初始化头结点如图5-5-4*/
  47. for (i = 0; i < num_heads; i++) {
  48. temp = new_node();
  49. hdnode[i] = temp;
  50. hdnode[i]->tag = head;
  51. hdnode[i]->right = temp;
  52. hdnode[i]->u.next = temp;
  53. }
  54. current_row = 0;
  55. last = hdnode[0];
  56. for (i = 0; i < num_terms; i++) {
  57. printf("Enter row, column and value: ");
  58. scanf("%d%d%d", &row, &col, &value);
  59. if (row > current_row) {
  60. /* 转到row所在行去*/
  61. last->right = hdnode[current_row];
  62. current_row = row;
  63. last = hdnode[row];
  64. }
  65. temp = new_node();
  66. temp->tag = entry;
  67. temp->u.entry.row = row;
  68. temp->u.entry.col = col;
  69. temp->u.entry.value = value;
  70. /* 链接到行结点上如图5-5-5所示 */
  71. last->right = temp;
  72. last = temp;
  73. /*链接到列结点上 */
  74. hdnode[col]->u.next->down = temp;
  75. hdnode[col]->u.next = temp;
  76. }
  77. /* 结束上一行结点 */
  78. last->right = hdnode[current_row];
  79. /*结束所有行结点*/
  80. for (i = 0; i < num_cols; i++)
  81. hdnode[i]->u.next->down = hdnode[i];
  82. /*链接所有的头结点 */
  83. for (i = 0; i < num_heads - 1; i++)
  84. hdnode[i]->u.next = hdnode[i + 1];
  85. hdnode[num_heads - 1]->u.next = node;
  86. node->right = hdnode[0];
  87. }
  88. return node;
  89. }
  90. void erase(matrix_pointer *node) {
  91. matrix_pointer x, y, head = (*node)->right;
  92. int i;
  93. /* 遍历每行,删除元素结点和头结点 */
  94. for (i = 0; i < (*node)->u.entry.row; i++) {
  95. y = head->right;
  96. while (y != head) {
  97. x = y;
  98. y = y->right;
  99. free(x);
  100. }
  101. x = head;
  102. head = head->u.next;
  103. free(x);
  104. }
  105. /* 删除剩余的头结点*/
  106. y = head;
  107. while (y != *node) {
  108. x = y;
  109. y = y->u.next;
  110. free(x);
  111. }
  112. free(*node);
  113. *node = NULL;
  114. }
  115. int main() {
  116. matrix_pointer matric = Create();
  117. erase(&matric);
  118. return 0;
  119. }

[数据结构]链表LinkList的更多相关文章

  1. [数据结构]链表相关的实现LinkList.cpp

    目录 LinkList.cpp //链表相关操作的实现 LinkList.h LinkListManager.cpp //链表相关实现函数的调用 LinkListManager.h LinkList. ...

  2. [PHP] 数据结构-链表创建-插入-删除-查找的PHP实现

    链表获取元素1.声明结点p指向链表第一个结点,j初始化1开始2.j<i,p指向下一结点,因为此时p是指向的p的next,因此不需要等于3.如果到末尾了,p还为null,就是没有查找到 插入元素1 ...

  3. Python—数据结构——链表

    数据结构——链表 一.简介 链表是一种物理存储上非连续,数据元素的逻辑顺序通过链表中的指针链接次序,实现的一种线性存储结构.由一系列节点组成的元素集合.每个节点包含两部分,数据域item和指向下一个节 ...

  4. (js描述的)数据结构[链表](4)

    (js描述的)数据结构 [链表](4) 一.基本结构 二.想比于数组,链表的一些优点 1.内存空间不是必须连续的,可以充分利用计算机的内存,事项灵活的内存动态管理. 2.链表不必再创建时就确定大小,并 ...

  5. 数据结构和算法(Golang实现)(12)常见数据结构-链表

    链表 讲数据结构就离不开讲链表.因为数据结构是用来组织数据的,如何将一个数据关联到另外一个数据呢?链表可以将数据和数据之间关联起来,从一个数据指向另外一个数据. 一.链表 定义: 链表由一个个数据节点 ...

  6. Redis数据结构—链表与字典的结构

    目录 Redis数据结构-链表与字典的结构 链表 Redis链表节点的结构 Redis链表的表示 Redis链表用在哪 字典 Redis字典结构总览 Redis字典结构分解 Redis字典的使用 Re ...

  7. Redis数据结构—链表与字典

    目录 Redis数据结构-链表与字典 链表 Redis链表节点的结构 Redis链表的表示 Redis链表用在哪 字典 Redis字典结构总览 Redis字典结构分解 哈希算法 解决键冲突 rehas ...

  8. Java数据结构与算法(5) - ch05链表(LinkList)

    双端链表与传统链表非常相似,但是它有一个新增的特性:即对最后一个链节点的引用,就像对第一个连接点的引用一样.注意与双向链表进行区别.

  9. Python 数据结构 链表

    什么是时间复杂度 时间频度:一个算法执行所耗费的时间,从理论上是不能算出来的,必须上机运行测试才知道.但是我们不可能也没有必要对每一个算法都进行上机测试,只需要知道那个算法花费的时间多,那个算法花费得 ...

随机推荐

  1. 14. GLIBCXX_3.4.9' not found - 解决办法

    在Linux中安装交叉编译器arm-linux-gcc 4.4.3,然后编译mini2440内核出错: /usr/lib/libstdc++.so.6: version GLIBCXX_3.4.9' ...

  2. Win7部署Yapi

    1.安装node 下载地址:https://nodejs.org/zh-cn/download/ (win7要下载v12.16之前的版本) 安装目录在D:\nodejs,配置地址(文件目录不能有特殊符 ...

  3. git 日志技术

    1.git log, 在一个分支下, 以时间的倒序方式显示你制造的所有commit列表,包含创建人,时间,提交了什么等信息: 2. git reflog, 获取您在本地repo上还原commit所做工 ...

  4. CentOS 7.3安装完整开发环境

    系统版本CentOS 7.3(1611) 安装开发环境1) 通过group安装 yum groups mark install "Development Tools" yum gr ...

  5. vscode高效管理不同项目文件

    vscode作为一个轻量级编辑器,深受大家喜爱,这其中当然也囊括了本人.我同时使用vscode写c++.java.python以及markdown文档,每次打开vscode都要切换到对应的文件夹,非常 ...

  6. 安全刻不容缓「GitHub 热点速览 v.21.50」

    作者:HelloGitHub-小鱼干 本周最热的事件莫过于 Log4j 漏洞,攻击者仅需向目标输入一段代码,不需要用户执行任何多余操作即可触发该漏洞,使攻击者可以远程控制用户受害者服务器,90% 以上 ...

  7. log4j漏洞的产生原因和解决方案,小白都能看懂!!!!

    核弹级bug Log4j,相信很多人都有所耳闻了,这两天很多读者都在问我关于这个bug的原理等一些问题,今天咱们就专门写一篇文章,一起聊一聊这个核弹级别的bug的产生原理以及怎么防止 产生原因 其实这 ...

  8. 【JAVA今法修真】 第四章 redis特性 击穿雪崩!

    感谢这段时间大家的支持,关注我的微信号:南橘ryc ,回复云小霄,就可以获取到最新的福利靓照一张,还等什么,赶快来加入我们吧~ "明日便是决赛了,咋只会用法器没练过法术呢.". 选 ...

  9. [BUUCTF]REVERSE——CrackRTF

    CrackRTF 附件 步骤: 例行查壳儿,32位程序,无壳儿 32位ida载入,main函数开始分析程序 破解第一个密码 sub_40100A()是一个加密函数,具体的写的算法没去分析,但是Cryp ...

  10. BUUCFT pwn asis2016_b00ks

    看师傅们wp的时候,我才知道这个道题是wiki上面的例题.我看了一些师傅的wp,发现大家都是一种做法,都是通过mmap堆地址,来找libc基地址的.而我试了一下fastbisn attack,发现也可 ...