链表—单链表、循环链表

目录

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.定义单链表

 typedef struct node{
     Datatype data;      //数据域
     struct node *next;  //指针域
 }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.在单链表中申请一个结点 

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

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

 //引用数据元素
     (*p).data
     p -> data
 //引用指针域
     (*p).next
     p -> next

1.3 存储结构

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

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

2.单链表的实现

2.1 遍历操作

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

 void displayNode(Link head){
     p = head -> next;
     while(p!=NULL){
         printf("%d",p->data);
         p = p->next;
     }
 }

2.2 求单链表的元素个数

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

 int length(Link head){
     p = head->next;
     count = 0;
     while(p != NULL){
         p=p->next;
         count++;
     }
     return count;
 }

2.3 查找操作

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

int queryNode(Link head,DataType x){
     p = head->next;
     while(p!=NULL){
         if(p->data==x){
             print(data);
             return ture;
         }
         p=p->next;
     }
     return false;  //没有找到
 }

2.4 插入操作

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

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

  • 边界情况:表头、表尾 

  • 算法描述

bool insertNode(Link head,int i,DataType x){
     p = head;   //工作指针指向头结点
     count = 0;
     while(p!=NULL & count <i-1){
         p = p->next;
         count++;
     }
     if(p == NULL){
         return false;  //没有找到第i个节点
     }else{
         node = (Link)malloc(sizeof(Node)); //申请一个结点
         node->data = x;
         node->next = p->next;
         p->next = node;
         return true;
     }
 }

2.5 创建单链表

1.头插法

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

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

插入第一个结点:

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

template <calss DataType>
 Link newList(DataType a[],int n){
     //创建头结点
     head = (Link)malloc(sizeof(Node));
     head->next = NULL;
     //创建后续结点
     for(int i = 0;i<n;i++){
         node = (Link)malloc(sizeof(Node));
         node->data = a[i];
         node->next = head->next;
         head-next = node;
     }
     return head;
 }

2.尾插法

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

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

 Link newList(DataType a[],int n){
     head = (Link)malloc(sizeof(Node));  //生成头结点
     head->next = NULL; 
     rear = head;  //初始化尾结点
     for(int i = 0;i<n;i++){
         node = (Link)malloc(sizeof(Node));
         node->data = a[i];
         rear->next = node;  
         /*node->next = NULL;*/
         rear = node;
     }
     rear->next = NULL;
     return head;
 }

2.6.单链表结点的删除

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

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

  • 算法描述:

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

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

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

 bool deleteNode(Link head,DataType x){
     if(head->next=NULL || head=NULL){  //空表,或者链表中没有数据
         return false;
     }
     p=head->next;  //初始化p,q
     q=p->head;
     while(p!=NULL){ 
         if(p->data == x){
             q->next = p->next;
             free(p);
             return true;
         }else{
             q=p;
             p=p->next;
         }
     }
     return flase;
 }

3循环链表的实现

  • 可以找到p的前驱结点 

3.1.插入

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

4双向链表

  • 快速找出前驱

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值