数据结构(6)线性表之双循环链表

本文介绍了双循环链表的概念,包括带头结点的空链表和非空链表结构。强调了双循环链表的插入和删除操作,无论头部还是尾部插入,都可视为按位置插入,并详细阐述了插入时涉及的指针调整。同时提到删除操作与插入类似,其他操作与双链表基本一致,但需注意循环条件的判断。提供了DCList的头文件、实现文件和主程序代码供参考。
摘要由CSDN通过智能技术生成

数据结构(6)线性表之双循环链表

前言

同单链表一样,双向链表也可以是循环表。链表最后一个结点的next指针指向头结点,头结点的Prior指针指向最后一个结点,形成循环。

带头结点的空链表

img_1

带头结点的非空链表

img_2

添加管理结构

img_3

双循环链表的插入与删除

实际上,在循环链表中,无论是头部插入还是尾部插入,都可以理解为按位置插入(就是在两个结点中间进行插入):头部插入是在头结点和首元结点之间进行插入,尾部插入则是在最后一个结点和头结点之间进行插入。这样,我们只需要知道如何在两个结点中间进行插入,就可以实现双循环链表诸多的插入操作。而如何在两个结点中间进行插入,跟在双链表中是一致的,也就是需要考虑四个指针的指向

  • 待插入结点的Prior指针

  • 待插入结点的Next指针

  • 待插入结点前驱的Next指针

  • 待插入结点后继的Prior指针

这样,本来区分开的头部插入、尾部插入操作可以整合为按位置插入,参数传要插入的位置即可。但是考虑到我们的双链表增加了管理结构,还需要保证管理结构指针的正确性,所以在代码中仍是区分实现的。

img_4

尾部插入也是两个结点中的插入

img_6

实际上

img_5

插入与删除类似

img_7
img_8
其他操作同双链表一致,只是判断循环结束的条件有区别罢了,不细说

全部代码

DCList.h
#ifndef DCList_h
#define DCList_h

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

#define ElemType int

typedef struct Node{
   
    ElemType data;
    struct Node *prior;
    struct Node *next;
}Node,*PNode;

typedef struct List{
   
    PNode first;
    PNode last;
    int size;
}List;

//初始化
void InitDCList(List *list);

//1.尾部插入
void push_back(List *list,ElemType x);
//2.头部插入
void push_fount(List *list,ElemType x);
//3.展示
void show_list(List *list);
//4.尾部删除
void pop_back(List *list);
//5.头部删除
void pop_fount(List *list);
//6.按值插入(要求插入前的链表是有序的(此处为顺序
void insert_val(List *list,ElemType x);
//7.按值查找
Node* find(List *list,ElemType x);
//8.获取长度
int length(List *list);
//9.按值删除
void  delete_val(List *list,ElemType x);
//10.排序
void sort(List *list);
//11.逆置(前后转换
void resver(List *list);
//12.清除单链表 ->只清除数据,保留头结点
void clearList(List *list);
//13.摧毁 ->包括头结点在内一起摧毁
void destroy(List *list);

//生成一个结点
Node* getNode(ElemType x);

#endif /* DCList_h */
DCList.cpp
#include "DCList.h"

//初始化
void InitDCList(List *list){
   
    //申请头结点
    Node *s = (Node *)malloc(sizeof(Node));
    assert(s != NULL);
    list->first = list->last = s;
    
    //使链表循环
    list->first->prior = list->last;
    list->last->next = list->first;

	list->size = 0;
}

//1.尾部插入
void push_back(List *list,ElemType x){
   
    Node *s = getNode(x);
    
    //s的前驱指向最后一个结点
    s->prior = list->last;
    //s的后继指向头结点
    s->next = list->last->next;
    //头结点的前驱指向s
    //list->last->next->prior = s;
    s->next->prior = s;
    //最后一个结点的后继指向s
    list->last->next = s;
    
    //重新设置last指针的值
    list->last = s;
    
    list->size ++</
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值