单向循环链表

单向循环链表

 单向链表是最简单的线性链式存储结构。可以通过头结点遍历整个链表。

 如上图所示,单向循环链表就是申请的一块块堆空间,通过指针将其串联起来,其中head指针存在栈空间,其内容存的是堆空间头结点的地址,所有操作都需要通过head指针来实现。
 使用结构体来实现单向循环链表,结构体中有数据域和指针域两个部分,其中数据域用来存储数据,指针域是指向下一个数据的。

typedef struct sgl_crclist{

      int data;
      struct sgl_crclist *next;
}my_sgl_crclist, *p_sgl_crclist;  

头节点设计


 新建一个单向循环链表,将其指针返回作为指向头结点的指针head。

p_sgl_crclist init_crclist()
{
      p_sgl_crclist head = new_node_crclist(); //新建一个节点作为头结点
      head->next = head;
      return head;
}

新建节点

 调用calloc函数新建一个节点,该函数返回新建节点的地址,方便后续操作。

p_sgl_crclist new_node_crclist()
{
      p_sgl_crclist new = calloc(1, sizeof(my_sgl_crclist));

      if(NULL == new)
      {
         return NULL;
      }
      return new;
}

插入数据

头插法

bool add_crclist(p_sgl_crclist head)
{
      int data;
      p_sgl_crclist new_node = new_node_crclist();  //新建节点
      p_sgl_crclist pos = head;

      printf("Please enter the data you want to insert:");
      scanf("%d", &data);
      while('
' != getchar());
      new_node->data = data;

      new_node->next = head->next;
      head->next = new_node;
}

尾插法

bool add_crclist_tail(p_sgl_crclist head)
{
      int data;
      p_sgl_crclist new_node = new_node_crclist();
      p_sgl_crclist pos = head;

      printf("Please enter the data you need to tail:");
      scanf("%d", &data);
      while('
' != getchar());
      new_node->data = data;

      while(pos->next != head)
      pos = pos->next;


      new_node->next = head;
      pos->next = new_node;
} 

打印链表数据

 一个一个节点移动指针pos,并取出里面的数据将其打印出来。

void display_crclist(p_sgl_crclist head)
{
      p_sgl_crclist pos = head->next;

      for(int i = 0; pos != head; i++)
      {
          printf("The data of node %d is:%d
", i, pos->data);
          pos = pos->next;
      }
}

查找数据

 查找链表中是否有某个数据,有的话返回该数据所在节点的地址。

p_sgl_crclist find_data(p_sgl_crclist head, int fdata)
{
      p_sgl_crclist pos = head->next;
      while(pos !=  head)
      {
          if(pos->data == fdata)
          {
                return pos;
          }
          else
          {
                pos = pos->next;
          }
       }

        printf("No data to found
");
        return NULL;
}

删除数据

 删除节点中的指定数据,此函数将调用函数find_data,用来获取指定数据所在的节点地址。

bool del_node_data(p_sgl_crclist head)
{
      int del_data;
      p_sgl_crclist delnode;
      p_sgl_crclist pos = head;

      printf("Please enter the data you want to delete:
");
      scanf("%d", &del_data);
      while('
' != getchar());

      delnode = find_data(head, del_data);
      if(delnode == NULL)
          return NULL;

      while(pos->next != delnode)
      {
          pos = pos->next;
          if(pos == NULL)
         {

              printf("node is error
");
              return NULL; 
         }
      }
        pos->next = delnode->next;
        delnode->next = NULL;
        return true;
}

更改数据

 将链表中的某个数据修改成指定数据,此函数将调用find_data,用来获取需要修改数据所在节点的地址。获取到地址后判断不为空时,直接修改即可。

bool mod_node_data(p_sgl_crclist head)
{
      int old_data;
      int new_data;

      p_sgl_crclist modnode;

      printf("Please enter the old and new data that need to be changed:");
      scanf("%d %d", &old_data, &new_data);
      while('
' != getchar());
      modnode = find_data(head, old_data);
      if(modnode == NULL)
         return false;

      modnode->data = new_data;
      return true;
}

测试代码

int test()
{
      p_sgl_crclist head = init_crclist();
      add_crclist(head);
      add_crclist(head);
      add_crclist(head);
      add_crclist(head);
      add_crclist(head);
      display_crclist(head);
      mod_node_data(head);
      display_crclist(head);
      .....
      .....
      return 0;
}
原文地址:https://www.cnblogs.com/ding-ding-light/p/14106025.html