数据结构与算法--线性表(CC老师).png

1. 单向循环链表创建

001.png

这里分两种情况判断是否是第一次创建:

  • YES->创建一个新结点,并使得新结点的next指向自身(L)->next = (L)
  • NO-> 找链表尾结点,将尾结点的next=新结点 新结点的next = (*L)

准备条件:

  1. #define ERROR 0
  2. #define TRUE 1
  3. #define FALSE 0
  4. #define OK 1
  5. #define MAXSIZE 20 /* 存储空间初始分配量 */
  6. typedef int Status;/* Status是函数的类型,其值是函数结果状态代码,如OK等 */
  7. typedef int ElemType;/* ElemType类型根据实际情况而定,这里假设为int */
  8. //定义结点
  9. typedef struct Node{
  10. ElemType data;
  11. struct Node *next;
  12. }Node;
  13. typedef struct Node * LinkList;

实现方式两种:
1.1 for循环遍历

  1. Status CreateList(LinkList *L){
  2. int item;
  3. LinkList temp = NULL;
  4. LinkList target = NULL;
  5. printf("输入节点的值,输入0结束\n");
  6. while(1)
  7. {
  8. scanf("%d",&item);
  9. if(item==0) break;
  10. //如果输入的链表是空。则创建一个新的节点,使其next指针指向自己 (*head)->next=*head;
  11. if(*L==NULL)
  12. {
  13. *L = (LinkList)malloc(sizeof(Node));
  14. if(!L)exit(0);
  15. (*L)->data=item;
  16. (*L)->next=*L;
  17. }
  18. else
  19. {
  20. //输入的链表不是空的,寻找链表的尾节点,使尾节点的next=新节点。新节点的next指向头节点
  21. for (target = *L; target->next != *L; target = target->next);
  22. temp=(LinkList)malloc(sizeof(Node));
  23. if(!temp) return ERROR;
  24. temp->data=item;
  25. temp->next=*L; //新节点指向头节点
  26. target->next=temp;//尾节点指向新节点
  27. }
  28. }
  29. return OK;
  30. }

1.2 临时变量记录最后一个

  1. Status CreateList2(LinkList *L){
  2. int item;
  3. LinkList temp = NULL;
  4. LinkList target = NULL;
  5. LinkList r = NULL;
  6. printf("请输入新的结点, 当输入0时结束!\n");
  7. while (1) {
  8. scanf("%d",&item);
  9. if (item == 0) {
  10. break;
  11. }
  12. //第一次创建
  13. if(*L == NULL){
  14. *L = (LinkList)malloc(sizeof(Node));
  15. if(!*L) return ERROR;
  16. (*L)->data = item;
  17. (*L)->next = *L;
  18. r = *L;
  19. }else{
  20. temp = (LinkList)malloc(sizeof(Node));
  21. if(!temp) return ERROR;
  22. temp->data = item;
  23. temp->next = *L;
  24. r->next = temp;
  25. r = temp;
  26. }
  27. }
  28. return OK;
  29. }

2. 单向链循环表插入

2.1 插入在首元结点

001.png**

2.2 插入在它位置

002.png

2.3 代码实现

  1. Status ListInsert(LinkList *L, int place, int num){
  2. LinkList temp ,target;
  3. int i;
  4. // place == 1 表示插入在首元结点
  5. if (place == 1) {
  6. //如果插入的位置为1,则属于插入首元结点,所以需要特殊处理
  7. //1. 创建新结点temp,并判断是否创建成功,成功则赋值,否则返回ERROR;
  8. //2. 找到链表最后的结点_尾结点,
  9. //3. 让新结点的next 执行头结点.
  10. //4. 尾结点的next 指向新的头结点;
  11. //5. 让头指针指向temp(临时的新结点)
  12. temp = (LinkList)malloc(sizeof(Node));
  13. if (temp == NULL) {
  14. return ERROR;
  15. }
  16. temp->data = num;
  17. for (target = *L; target->next != *L; target = target->next);
  18. temp->next = *L;
  19. target->next = temp;
  20. *L = temp;
  21. } else
  22. {
  23. //如果插入的位置在其他位置;
  24. //1. 创建新结点temp,并判断是否创建成功,成功则赋值,否则返回ERROR;
  25. //2. 先找到插入的位置,如果超过链表长度,则自动插入队尾;
  26. //3. 通过target找到要插入位置的前一个结点, 让target->next = temp;
  27. //4. 插入结点的前驱指向新结点,新结点的next 指向target原来的next位置 ;
  28. temp = (LinkList)malloc(sizeof(Node));
  29. if (temp == NULL) {
  30. return ERROR;
  31. }
  32. temp->data = num;
  33. for ( i = 1,target = *L; target->next != *L && i != place - 1; target = target->next,i++) ;
  34. temp->next = target->next;
  35. target->next = temp;
  36. }
  37. return OK;
  38. }

3. 单向循环链表删除实现

链表的删除同样也是分两种情况:

  • 删除首元结点
  • 删除其他结点

    1. Status LinkListDelete(LinkList *L,int place){
    2. LinkList temp,target;
    3. int i;
    4. //temp 指向链表首元结点
    5. temp = *L;
    6. if(temp == NULL) return ERROR;
    7. if (place == 1) {
    8. //①.如果删除到只剩下首元结点了,则直接将*L置空;
    9. if((*L)->next == (*L)){
    10. (*L) = NULL;
    11. return OK;
    12. }
    13. //②.链表还有很多数据,但是删除的是首结点;
    14. //1. 找到尾结点, 使得尾结点next 指向头结点的下一个结点 target->next = (*L)->next;
    15. //2. 新结点做为头结点,则释放原来的头结点
    16. for (target = *L; target->next != *L; target = target->next);
    17. temp = *L;
    18. *L = (*L)->next;
    19. target->next = *L;
    20. free(temp);
    21. }else
    22. {
    23. //如果删除其他结点--其他结点
    24. //1. 找到删除结点前一个结点target
    25. //2. 使得target->next 指向下一个结点
    26. //3. 释放需要删除的结点temp
    27. for(i=1,target = *L;target->next != *L && i != place -1;target = target->next,i++) ;
    28. temp = target->next;
    29. target->next = temp->next;
    30. free(temp);
    31. }
    32. return OK;
    33. }

    4. 单向循环链表查询值

    1. int findValue(LinkList L,int value){
    2. int i = 1;
    3. LinkList p;
    4. p = L;
    5. //寻找链表中的结点 data == value
    6. while (p->data != value && p->next != L) {
    7. i++;
    8. p = p->next;
    9. }
    10. //当尾结点指向头结点就会直接跳出循环,所以要额外增加一次判断尾结点的data == value;
    11. if (p->next == L && p->data != value) {
    12. return -1;
    13. }
    14. return i;
    15. }