数据结构(C语言版)学习笔记3-双向循环链表

双向循环链表

1.线性表的双向链表存储结构

双向链表的结点含有两个指针域,其一指向直接后继,另一指向直接前驱,可描述为:

typedef struct DuLNode{
    DuElemType data;
    struct DuLNode *prior;
    struct DuLNode *next;
}DuLNode,*DuLinkList;

2.双向循环链表基本操作


//1.双链表初始化(带头结点)
DuLNode *D_creatslink(int i);
//2.求链长(带头结点)
DuElemType D_ListLengths(DuLNode*head);
//3.取链表内元素
int D_GetElems(DuLNode*L,int i,DuElemType*t);
//4.插入操作
int D_InsertLists(DuLNode*L,int i,DuElemType e);
//5.删除操作
int D_DeleteLists(DuLNode*L,int i);
//6.定位操作
int D_LocateLists(DuLNode*L,DuElemType e);
//7.输出链表
void D_Lists(DuLNode*L);
//8.利用头结点反向输出输出链表
void BD_Lists(DuLNode*L);

3.完整程序

完整程序包括三个文件:

D_main.c(主程序)
–用于测试双向循环链表基本操作
D_linklist.h
标准库导入,存放类型定义,符号定义等预定义内容及函数声明。
D_linklist.c
存放双向循环链表基本操作函数主体内容。

①D_main.c

/*D_main.c*/
#include"D_linklist.h"

void main()
{
    DuLinkList L;//创建一个结点指针
    int j;
    L=D_creatslink(5);
    printf("表长为:%d\n",D_ListLengths(L));
    D_Lists(L);
    D_GetElems(L,5,&j);
    printf("表内第5号元素为:%d\n",j);
    D_InsertLists(L,5,666);
    D_Lists(L);
    printf("'99'为第%d号元素.\n",D_LocateLists(L,99));
    D_DeleteLists(L,5);
    D_Lists(L);
    BD_Lists(L);

}

②D_linklist.h

/*D_linklist.h*/
#ifndef _D_LINKLIST_H
#define _D_LINKLIST_H

typedef int DuElemType; 
#include<stdio.h>
#include<stdlib.h>

typedef struct DuLNode{
    DuElemType data;
    struct DuLNode *prior;
    struct DuLNode *next;
}DuLNode,*DuLinkList;


/*基本操作声明*/
//1.双链表初始化(带头结点)
DuLNode *D_creatslink(int i);
//2.求链长(带头结点)
DuElemType D_ListLengths(DuLNode*head);
//3.取链表内元素
int D_GetElems(DuLNode*L,int i,DuElemType*t);
//4.插入操作
int D_InsertLists(DuLNode*L,int i,DuElemType e);
//5.删除操作
int D_DeleteLists(DuLNode*L,int i);
//6.定位操作
int D_LocateLists(DuLNode*L,DuElemType e);
//7.输出链表
void D_Lists(DuLNode*L);
//8.利用头结点反向输出输出链表
void BD_Lists(DuLNode*L);


#endif

③D_linklist.c

/*D_linklist.c*/
#include"D_linklist.h"

//1.双链表初始化(带头结点)
DuLNode *D_creatslink(int i)
{
    DuLNode*prior,*next,*head,*s,*p;    
    int n;                                          //循环控制变量
    head=p=s=(DuLNode*)malloc(sizeof(DuLNode));     //创建一个结点作为头结点,并使头指针指向它
    for(n=0;n<i;n++)                                //循环i次,创建i个结点
    {
        s=(DuLNode*)malloc(sizeof(DuLNode));        //创建一个结点
        printf("请输入第%d个元素:",n+1);
        scanf("%d",&s->data);                       //数据域赋值
        p->next=s;                                  //使上一个结点的next指针指向刚创建的结点
        s->prior=p;                                 //将创建的结点的头指针指向上一个结点
        p=s;                                        //移动P指针,使其指向当前结点
    }
    p->next=head;                                   //尾结点的尾指向头指针
    head->prior=p;                                  //头结点的头结点指向尾结点
    printf("双向循环列表建立成功!head:%d \n",head);

    return head;
}
//2.求链长(带头结点)
DuElemType D_ListLengths(DuLNode*head)
{
    DuLNode *p,*t;
    int n;                  //链表记录变量
    p=head->next;           //跳过头结点
    for(n=1;p!=head;n++)    //循环历遍记录长度
        p=p->next;
    if(p==head)return n;
    else return 0;
}

//3.取链表内元素
int D_GetElems(DuLNode*L,int i,DuElemType*t)
{
    int n;
    DuLNode*p=L;
    if(i<1 || i>D_ListLengths(L))return 0;    //参数i不合理,取元素失败返回0
    for(n=0;n<i;n++)                          //循环历遍结点个数
        p=p->next;
    *t=p->data;                               //其值通过指针t返回
    return 1;
}
//4.插入操作
int D_InsertLists(DuLNode*L,int i,DuElemType e)
{
    DuLNode*p=L,*t,*f;
    int n;
    if(i<1 || i>D_ListLengths(L))return 0;
    else{
        for(n=0;n<i-1;n++)                          //循环历遍,直到i-1个位置
            p=p->next;  
        f=p;                                        //f指针存储第i-1个元素所在结点的地址
        t=p->next;                                  //t指针存储第i+1个元素所在结点的地址
        p->next=(DuLNode*)malloc(sizeof(DuLNode));  //创建一个新结点,并将第i-1个元素所在结点的next指针指向新结点
        p=p->next;                                  //移动p,使其指向新结点
        p->data=e;                                  //给新结点数据域赋值
        p->prior=f;                                 //新结点的prior指针指向第i-1个元素所在结点
        p->next=t;                                  //新结点的next指针指向第i+1个元素所在结点
        t->prior=p;                                 //第i+1个元素所在结点的prior指针指向新结点
    return 1;
    }
}
//5.删除操作
int D_DeleteLists(DuLNode*L,int i)
{
    DuLNode*p=L,*t,*s;
    int n;
    if(i<1 || i>D_ListLengths(L))return 0;
    else{
        for(n=0;n<i-1;n++)
            p=p->next;
        t=p->next;      //t为待删除结点地址
        p->next=t->next;//p为待删除结点上一个结点
        s=t->next;      //s为待删除结点下一个结点
        s->prior=p;     //含第i+1个元素的结点prior指针指向含第i-1个元素的结点
        free(t);        //释放含第i个元素的结点空间
    return 1;
    }
}
//6.定位操作
int D_LocateLists(DuLNode*L,DuElemType e)
{
    DuLNode*p=L->next;
    int n;
    for(n=1;p->data!=e && p!=L;n++) //通过循环历遍寻找值e
        p=p->next;
    if(p->data == e)                //找到,返回位序
        return n;
    else                            //没找到,返回0
        return 0;
}
//7.输出链表
void D_Lists(DuLNode*L)
{
    DuLNode*p=NULL;
    p=L->next;                      //将P指向头结点
    printf("链表内元素为:\n");
    while(p!=L && p->data)
    {
        printf("-%d",p->data);
        p=p->next;
    }
    printf("\n");
}
//8.利用头结点反向输出输出链表
void BD_Lists(DuLNode*L)
{
    DuLNode*p=NULL;
    p=L->prior;
    printf("链表内元素为:\n");
    while(p!=L && p->data)
    {
        printf("-%d",p->data);
        p=p->prior;
    }
    printf("\n");
}

本次学习笔记如上所示,不足之处欢迎大家批评指正。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值