《大话数据结构》读书笔记之线性表抽象数据类型(双向循环链表实现)

本文介绍了一种使用双向循环链表来实现线性表抽象数据类型的详细方法,包括创建、插入、删除等核心操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/*
Name: 线性表抽象数据类型(使用双向循环链表实现) 
Copyright: 
Author: 巧若拙 
Date:13-09-14 17:07
Description: 
*/


#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
#include<math.h>


#define MAXSIZE 10
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0 


typedef int ElemType;
typedef int Status; //函数类型,其值是函数结果状态代码,如OK等 


typedef struct DuNode{
ElemType data;//数据域 
struct DuNode *prior;//直接前驱指针 
struct DuNode *next;//直接后继指针 
} DuNode, *DuLinkList;


Status InitList(DuLinkList *L);//建立一个带头结点的空线性表L 
Status ListEmpty(DuLinkList L);//判断线性表是否为空,若线性表为空,返回TRUE,否则返回FALSE
Status ClearList(DuLinkList *L);//将线性表清空(只留下头结点)
int ListLength(DuLinkList L);//返回线性表L的元素个数 
Status DisplayList(DuLinkList L);//输出线性表L的所有元素
Status GetElem(DuLinkList L, int i, ElemType *e);//将线性表L中第i个位置元素值赋给e 
Status LocateElem(DuLinkList L, ElemType e);//在线性表L中查找是否存在与给定值e相等的元素
Status ListInsert(DuLinkList *L, int i, ElemType e);//在线性表L中的第i个位置之前插入新元素e 
Status ListDelete(DuLinkList *L, int i, ElemType *e);//删除线性表L中的第i个位置,并将该元素值赋给e 


int main(void)
{
    DuLinkList a = NULL;
    ElemType *p, e = 0;
    int i;
    
    InitList(&a);//建立一个空的线性表
    
    ListInsert(&a, 1, 1);
    for (i=1; i<MAXSIZE; i++)
    {
    ListInsert(&a, i, i+100);
    }
    
    DisplayList(a);
    
    printf("len = %d\n", ListLength(a));
    for (i=1; i<ListLength(a); i+=2)
    {
    ListDelete(&a, i, &e);//删除线性表L中的第i个位置,并将该元素值赋给e 
    }
    printf("len = %d\n", ListLength(a));
    printf("e = %d\n", e);
    
    DisplayList(a);
    
    i = 5;
    e = 1050;
    if (LocateElem(a, e))//在线性表L中查找是否存在与给定值e相等的元素
    {
    printf("存在%d\n", e);
    }
    else
    {
    printf("不存在%d\n", e);
    ListInsert(&a, i, e);
    }
    
    DisplayList(a);
    
    ListDelete(&a, ListLength(a), &e);//删除线性表L中的最后一个元素 
    DisplayList(a);
    
    ListDelete(&a, 1, &e);//删除线性表L中的第一个元素 
    DisplayList(a);
    
    ClearList(&a);//将线性表清空(只留下头结点)
    DisplayList(a);
   
    return 0;
}


/*
函数功能:建立一个带头结点的空线性表L 
初始条件:无
操作结果:初始化线性表L。操作成功返回OK,否则返回ERROR  
*/
Status InitList(DuLinkList *L)//建立一个带头结点的空线性表L  
{
*L = (DuLinkList)malloc(sizeof(DuNode));


if (!(*L))
{
printf("Out of space!");
return ERROR;
}

(*L)->prior = (*L)->next = (*L);

return OK;





/*
函数功能:判断线性表是否为空
初始条件:双向循环链表线性表L已经存在
操作结果:若线性表为空,返回TRUE,否则返回FALSE 
*/
Status ListEmpty(DuLinkList L)
{
return (L->next == L) ? TRUE : FALSE;
}


/*
函数功能:将线性表清空 
初始条件:双向循环链表线性表L已经存在
操作结果:将线性表清空(只留下头结点)。操作成功返回OK,否则返回ERROR  
*/
Status ClearList(DuLinkList *L)
{
DuLinkList p, q;

if (*L == NULL)
{
return ERROR;
}

p = (*L)->next; //p指向第一个结点(非头结点)
while (p != (*L))
{
q = p->next;
(*L)->next = q;
q->prior = *L;
free(p);
p = q;


return OK;
}


/*
函数功能:返回线性表L的元素个数 
初始条件:双向循环链表线性表L已经存在
操作结果:返回线性表L的元素个数 
*/
int ListLength(DuLinkList L)
{
DuLinkList p = L->next;
int i = 0;

while (p != L)
{
i++;
p = p->next;
}

return i;
}


/*
函数功能:输出线性表L的所有元素
初始条件:双向循环链表线性表L已经存在
操作结果:输出线性表L的所有元素。操作成功返回OK,否则返回ERROR 
*/
Status DisplayList(DuLinkList L)
{
int i = 1;
DuLinkList p = L->next;

while (p == L)
{
printf("none!\n");
return ERROR;
}

while (p != L)
{
printf("data[%d] = %d, ", i++, p->data);
p = p->next;
}
    printf("\n");

    return OK;
}


/*
函数功能:将线性表L中第i个位置元素值赋给e 
初始条件:双向循环链表线性表L已经存在,1 <= i <= ListLength(L);
操作结果:将线性表L中第i个位置元素值赋给e。操作成功返回OK,否则返回ERROR 
*/
Status GetElem(DuLinkList L, int i, ElemType *e)
{
int j = 1;
DuLinkList p = L->next; //p指向第一个结点(非头结点)

while (p != L && j < i) //寻找第i个结点 
{
j++;
p = p->next;
}

if (p == L || j > i) //第i个元素不存在 
{
return ERROR;
}

*e = p->data;

return OK;
}


/*
函数功能:在线性表L中查找是否存在与给定值e相等的元素
初始条件:双向循环链表线性表L已经存在
操作结果:在线性表L中查找是否存在与给定值e相等的元素。找到返回TRUE,否则返回FALSE 
*/
Status LocateElem(DuLinkList L, ElemType e)
{
DuLinkList p = L->next; //p指向第一个结点(非头结点)

while (p != L)
{
if (p->data == e)
{
return TRUE;
}
p = p->next;
}

return FALSE;



/*
函数功能:在线性表L中的第i个位置之前插入新元素e 
初始条件:双向循环链表线性表L已经存在,1 <= i <= ListLength(L);
操作结果:在线性表L中的第i个位置之前插入新元素e。操作成功返回OK,否则返回ERROR  
*/
Status ListInsert(DuLinkList *L, int i, ElemType e)
{
DuLinkList s, p = (*L)->next; //p指向第一个结点(非头结点)
int j = 1;

if (i == 1 && ListEmpty(*L))//空表,插入第一个元素
{
goto INSERT;


while (p != *L && j < i)//寻找第i个结点 
{
j++;
p = p->next;
}


if (p == *L || j > i) //第i个结点不存在 
{
return ERROR;
}

INSERT:
s = (DuLinkList)malloc(sizeof(DuNode));
if (!s)
{
printf("Out of space!");
return ERROR;
}

s->data = e;
s->next = p;
s->prior = p->prior;
s->prior->next = s;
p->prior = s;

return OK;
}


/*
函数功能:删除线性表L中的第i个位置,并将该元素值赋给e 
初始条件:双向循环链表线性表L已经存在,1 <= i <= ListLength(L);
操作结果:删除线性表L中的第i个位置,并将该元素值赋给e。
操作成功返回OK,否则返回ERROR  
*/
Status ListDelete(DuLinkList *L, int i, ElemType *e)
{
DuLinkList q, p = (*L)->next; //p指向第一个结点(非头结点)
int j = 1;

while (p != *L && j < i)//寻找第i个结点 
{
j++;
p = p->next;
}

if (p == *L || j > i) //第i个结点不存在 
{
return ERROR;
}

q = p->next; 
q->prior = p->prior;
q->prior->next = q;
*e = p->data;
free(p);

return OK;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值