[关闭]
@Arbalest-Laevatain 2018-10-17T02:29:57.000000Z 字数 1953 阅读 754

链表

数据结构


单链表

单链表即只能向一个方向的遍历的链表,换句话说,就是只有一个指针(域)(指向后面或前面),单链表是最简单的链表。
又因为在单链表中,每次读取元素,都要从头结点开始,故单链表是一种非随机存取的存储结构

结点定义

  1. typedef struct LNodes
  2. {
  3. ElemType data;
  4. struct LNodes *next;
  5. } LNodes,*LinkList;

结点初始化

  1. if (p!=NULL)
  2. {
  3. p->data=10;
  4. p->next=NULL;
  5. }

建立链表

  1. LinkedList LinkedListInit() {
  2. Node *L;
  3. L = (Node *)malloc(sizeof(Node)); //申请结点空间
  4. if(L == NULL) { //判断是否有足够的内存空间
  5. printf("申请内存空间失败\n");
  6. }
  7. L->next = NULL; //将next设置为NULL,初始长度为0的单链表
  8. return L;
  9. }
  10. //单链表的建立1,头插法建立单链表
  11. LinkedList LinkedListCreatH() {
  12. Node *L;
  13. L = (Node *)malloc(sizeof(Node)); //申请头结点空间
  14. L->next = NULL; //初始化一个空链表
  15. ElemType x; //x为链表数据域中的数据
  16. while(scanf("%d",&x) != EOF) {
  17. Node *p;
  18. p = (Node *)malloc(sizeof(Node)); //申请新的结点
  19. p->data = x; //结点数据域赋值
  20. p->next = L->next; //将结点插入到表头L-->|2|-->|1|-->NULL
  21. L->next = p;
  22. }
  23. return L;
  24. }

遍历一个链表

访问函数

  1. Status printElement(Elemtype e)
  2. {
  3. printf("%c",e); //假设是char类型
  4. return OK;
  5. }

遍历函数

  1. void TraverseLinkList(LinkList L,Status(*visit)(ElemType e))
  2. {
  3. LNode *p;
  4. p=L;
  5. while (p!=NULL)
  6. {
  7. visit(p->data);
  8. p=p->next;
  9. }
  10. }

我的测试代码

demo02

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #define TRUE 1
  4. #define FALSE 0
  5. #define OK 1
  6. #define ERROR 0
  7. #define OVERFLOW -1
  8. typedef int Status;
  9. //结点定义
  10. typedef struct LNodes
  11. {
  12. int data;
  13. struct LNodes *next;
  14. } *LinkList;
  15. LinkList chushihua()
  16. {
  17. LNodes *L;
  18. L = (struct LNodes *) malloc (sizeof(struct LNodes)); //申请头结点空间
  19. //L->data = 0;
  20. L->next = NULL; //初始化一个空链表
  21. int x; //x为链表数据域中的数据
  22. while (scanf_s("%d", &x) != EOF)
  23. {
  24. struct LNodes *p;
  25. p = (struct LNodes *)malloc(sizeof(struct LNodes)); //申请新的结点
  26. p->data = x; //结点数据域赋值
  27. p->next = L->next; //将结点插入到表头L-->|2|-->|1|-->NULL
  28. L->next = p;
  29. }
  30. return L;
  31. }
  32. Status printElement(int e)
  33. {
  34. printf("%d\n", e); //假设是int类型
  35. return OK;
  36. }
  37. void bianli(struct LNodes *L)
  38. {
  39. struct LNodes *p;
  40. p = L->next;
  41. while (p != NULL)
  42. {
  43. if (printElement(p->data))
  44. p = p->next;
  45. }
  46. free(L);
  47. free(p);
  48. }
  49. int main()
  50. {
  51. struct LNodes *L;
  52. int n;
  53. L=chushihua();
  54. bianli(L);
  55. //printf("%d\n",scanf_s("%d",&n));
  56. return 0;
  57. }

相关操作

判断是否为空

如何在其他没有指针的高级语言中使用链表?

这时我们应该借用一维数组来定义:

  1. #define Maxsize 1000
  2. typedef struct
  3. {
  4. ElemType data;
  5. int cur; //数组下标,来代替指针
  6. }compnent,SLinkList[Maxsize];

这种链表,与前面的不一样为静态线性链表。

带头结点的单链表

典型应用

循环单链表

与单链表唯一的区别在于,最后一个结点的后继指向头结点,但就这一个区别,就会造成后后面有很多地方与单链表不同。

双链表

与单链表对应的,双链表是同时可以向前又可以向后遍历的链表,即同时具有两个指针(一前一后)

循环双链表

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注