当前位置:   article > 正文

链表—单链表、循环链表_单链表和循环单链表

单链表和循环单链表

目录

1.单链表

1.1单链表存储特点:

1.2 单链表的结点结构

1.定义单链表

2.在单链表中申请一个结点 

3.引用数据元素和指针域

1.3 存储结构

2.单链表的实现

2.1 遍历操作

2.2 求单链表的元素个数

2.3 查找操作

2.4 插入操作

2.5 创建单链表

1.头插法

2.尾插法

2.6.单链表结点的删除

3循环链表的实现

3.1.插入

3.2.特点——没有明显的尾端

4双向链表


1.单链表

1.1单链表存储特点:

  1. 逻辑次序和物理次序不一定相同

  2. 元素之间的逻辑关系用指针表示

  • 举例:(a1,a2,a3,a4)的存储示意图

  • 存储信息的这个单元我们称之为结点,一个结点包括数据域(存储当前信息)和指针域(存储下一结点的地址)。

  • 单链表是由若干结点构成的,单链表的结点只有一个指针域:

单链表的结点结构: 

1.2 单链表的结点结构

1.定义单链表

  1.  typedef struct node{
  2.      Datatype data;      //数据域
  3.      struct node *next;  //指针域
  4.  }Node,*Link;  //*Link:指向结构体的指针

使用typedef定义,Node,和*Link就相当于声明了一个类型

  • Node st : 等价于 struct node st;

    Link p : 等价于 struct node *p;

    p = (Link) malloc(sizeof(Node));

    等价于:

    p = (struct node *) malloc(sizeof(Node))

2.在单链表中申请一个结点 

  1. //申请一个结点
  2.  Link p;
  3.  p = (Link)malloc(sizeof(Node));

3.引用数据元素和指针域

  1.  //引用数据元素
  2.   (*p).data
  3.   p -> data
  4.  //引用指针域
  5.     (*p).next
  6.      p -> next

1.3 存储结构

  • 重点在数据元素之间的逻辑关系表示,将实际存储地址抽象 

  • 将空表与非空表进行统一处理:头结点

2.单链表的实现

2.1 遍历操作

  • 操作接口:void displayNode(Link head);

  1.  void displayNode(Link head){
  2.      p = head -> next;
  3.      while(p!=NULL){
  4.          printf("%d",p->data);
  5.          p = p->next;
  6.     }
  7.  }

2.2 求单链表的元素个数

  • 操作接口:int length(Link head); 

  1.  int length(Link head){
  2.      p = head->next;
  3.      count = 0;
  4.      while(p != NULL){
  5.          p=p->next;
  6.          count++;
  7.   }
  8.      return count;
  9.  }

2.3 查找操作

  • 操作接口: int queryNode(Link head,DataType x); 

  1. int queryNode(Link head,DataType x){
  2.      p = head->next;
  3.      while(p!=NULL){
  4.          if(p->data==x){
  5.              print(data);
  6.              return ture;
  7.         }
  8.          p=p->next;
  9.     }
  10.      return false;  //没有找到
  11.  }

2.4 插入操作

  • 操作接口:void inserNode(Link head,int i,dataType x);

  • 结点ai-1、x和ai之间的逻辑关系 

  • 边界情况:表头、表尾 

  • 算法描述

  1. bool insertNode(Link head,int i,DataType x){
  2.      p = head;   //工作指针指向头结点
  3.      count = 0;
  4.      while(p!=NULL & count <i-1){
  5.          p = p->next;
  6.          count++;
  7.     }
  8.      if(p == NULL){
  9.          return false;  //没有找到第i个节点
  10.     }else{
  11.          node = (Link)malloc(sizeof(Node)); //申请一个结点
  12.          node->data = x;
  13.          node->next = p->next;
  14.          p->next = node;
  15.          return true;
  16.     }
  17.  }

2.5 创建单链表

1.头插法

  • 操作接口: Link newList(Datatype a[],int n);

  • 头插法:将插入的结点插在头结点的后面

插入第一个结点:

  •  再依次插入每一个结点
  • 特点:头插法的顺序与数组顺序相反

  1. template <calss DataType>
  2.  Link newList(DataType a[],int n){
  3.   //创建头结点
  4.      head = (Link)malloc(sizeof(Node));
  5.      head->next = NULL;
  6.      //创建后续结点
  7.      for(int i = 0;i<n;i++){
  8.          node = (Link)malloc(sizeof(Node));
  9.          node->data = a[i];
  10.          node->next = head->next;
  11.          head-next = node;
  12.   }
  13.      return head;
  14.  }

2.尾插法

  • 操作接口:Link newList(Datatype a[],int n);

  • 尾插法:将待插入的结点插在终端结点的后面 

  1.  Link newList(DataType a[],int n){
  2.      head = (Link)malloc(sizeof(Node));  //生成头结点
  3.      head->next = NULL;
  4.      rear = head;  //初始化尾结点
  5.      for(int i = 0;i<n;i++){
  6.          node = (Link)malloc(sizeof(Node));
  7.          node->data = a[i];
  8.          rear->next = node;  
  9.          /*node->next = NULL;*/
  10.          rear = node;
  11.   }
  12.      rear->next = NULL;
  13.      return head;
  14.  }

2.6.单链表结点的删除

  • 操作接口:bool deleteNode(Link head,DataType x);

  • 正在上传…重新上传取消

  • 算法描述:

    1.  q-next = p->next;
    2.  free(p);
  • 空表情况,判断

    1.  if(head = NULL ||head->next = NULL){ //空表
    2.      return false;
    3.  }

  • 正在上传…重新上传取消

  1.  bool deleteNode(Link head,DataType x){
  2.      if(head->next=NULL || head=NULL){  //空表,或者链表中没有数据
  3.          return false;
  4.     }
  5.      p=head->next;  //初始化p,q
  6.      q=p->head;
  7.      while(p!=NULL){
  8.          if(p->data == x){
  9.              q->next = p->next;
  10.              free(p);
  11.              return true;
  12.         }else{
  13.              q=p;
  14.              p=p->next;
  15.         }
  16.     }
  17.      return flase;
  18.  }

3循环链表的实现

  • 可以找到p的前驱结点 

3.1.插入

3.2.特点——没有明显的尾端

4双向链表

  • 快速找出前驱

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/474557
推荐阅读
相关标签
  

闽ICP备14008679号