数据结构-双向循环链表(无头结点)相关算法

#include <stdio.h>
#include <stdlib.h>
#define OVERFLOW -2
#define OK 1
#define ERROR 0

//此双向循环链表无头结点
typedef int ElemType;
typedef struct DulNode {
    ElemType data;
    struct DulNode *prior;
    struct DulNode *next;
}DulNode,*DulLinkList;

DulLinkList InitList_Dul(DulLinkList L);
DulLinkList CreateElemP_Dul(DulLinkList L);
void PrintList_Dul(DulLinkList L);
int GetElemP1_Dul(DulLinkList L,int i,ElemType *e);
DulLinkList ListInsert_Dul(DulLinkList L,int i,ElemType e);
int ListLength_Dul(DulLinkList L);
DulLinkList GetElemP2_Dul(DulLinkList L,int i);
DulLinkList ListInsert_Dul(DulLinkList L,int i,ElemType e);
DulLinkList ListDelete_Dul(DulLinkList L,int i,ElemType *e);
int GetLocate_Dul(DulLinkList L,ElemType e);
int main()
{
    DulLinkList dul;
    int len,loc;
    ElemType e;
    dul = InitList_Dul(dul);
    dul = CreateElemP_Dul(dul);
    len = ListLength_Dul(dul);
    printf("该双向链表的长度为:%d\n",len);
    PrintList_Dul(dul);
    GetElemP1_Dul(dul,3,&e);//3为元素所在的位序
    printf("第i个位置的元素为:%d\n",e);
    printf("向链表中插入一个元素后:");
    dul = ListInsert_Dul(dul,1,0);//1为插入元素的位置
    PrintList_Dul(dul);
    printf("从链表删除一个元素后:");
    dul = ListDelete_Dul(dul,2,&e);//2为删除元素的位序
    PrintList_Dul(dul);
    printf("删除的元素是:%d\n",e);
    loc = GetLocate_Dul(dul,0);//0为元素的值
    printf("该双向循环链表元素i的位序为:%d\n",loc);
    return 0;
}

//初始化一个双向循环链表
DulLinkList InitList_Dul(DulLinkList L) {
    L = (DulLinkList)malloc(sizeof(DulNode));
    if(L != NULL) {
        L->next = L->prior = L;
    } else {
        exit(OVERFLOW);
    }
    return L;

}

//创建一个双向循环链表
DulLinkList CreateElemP_Dul(DulLinkList L) {
    int n,i;
    DulLinkList p,s;
    s = L;
    printf("请输入双向循环链表的元素个数:");
    scanf("%d",&n);
    printf("请输入双向循环链表中元素的值:");
    for(i=0; i<n; i++) {
        p = (DulLinkList)malloc(sizeof(DulNode));
        scanf("%d",&p->data);
        p->prior = s->prior;
        s->prior->next = p;
        p->next = s;
        s->prior = p;
    }
    return L;
}

//输出该双向循环链表
void PrintList_Dul(DulLinkList L) {
    int i;
    DulLinkList p;
    p = L;
    printf("该循环链表中的元素为:");
    while(p->next != L) {
        p = p->next;
        printf("%d ",p->data);
    }
    printf("\n");
}

//返回双向循环链表的长度
int ListLength_Dul(DulLinkList L) {
    DulLinkList p;
    int i;
    p = L->next;
    i = 0;
    while((p!=L) && (p!=NULL)) {
        ++i;
        p = p->next;
    }
    return i;
}

//取得双向循环链表上第i个位置上的元素的值
int GetElemP1_Dul(DulLinkList L,int i,ElemType *e) {
    DulLinkList p;
    int j;
    p = L;
    j = 0;
    while(p->next && j<i) {
        ++j;
        p = p->next;
    }
    if(!p || j>i) return ERROR;
    *e = p->data;
    return OK;
}

//返回双向循环链表上第i个位置上的指针
DulLinkList GetElemP2_Dul(DulLinkList L,int i) {
    DulLinkList p;
    int j;
    p = L;
    j = 0;
    while(p->next && j<i) {
        ++j;
        p = p->next;
    }
    if(!p || j>i) return ERROR;
    return p;
}

//向该双向循环链表的第i个位置之前插入元素e
DulLinkList ListInsert_Dul(DulLinkList L,int i,ElemType e) {
    DulLinkList p,s;
    int m;
    if(!(p=GetElemP2_Dul(L,i))) {
        return ERROR;
    }

if(!(s = (DulLinkList)malloc(sizeof(DulNode)))) {
        return ERROR;
    }
    s->data = e;
    s->prior = p->prior;
    p->prior->next = s;
    s->next = p;
    p->prior = s;
    return L;
}

//删除双向循环链表上第i个位置的元素,并返回该元素的值
DulLinkList ListDelete_Dul(DulLinkList L,int i,ElemType *e) {
    DulLinkList p;
    if(!(p=GetElemP2_Dul(L,i))) {
        return ERROR;
    }
    *e = p->data;
    p->prior->next = p->next;
    p->next->prior = p->prior;
    return L;
}

//返回双向循环链表上元素e的位序
int GetLocate_Dul(DulLinkList L,ElemType e) {
    DulLinkList p;
    int j;
    p = L->next;
    j = 0;
    while((p != L) && (p->data!=e)) {
        j++;
    }
    return j;
}

时间: 2024-10-08 17:48:21

数据结构-双向循环链表(无头结点)相关算法的相关文章

Java数据结构 - 双向循环链表

class DoubleLoopNode { // 上一个节点 DoubleLoopNode pre; // 下一个节点 DoubleLoopNode next; // 节点的内容 int data; public DoubleLoopNode(int value) { this.pre = this; this.next = this; this.data = value; } // 插入节点 public void append(DoubleLoopNode node) { // 原来的下一

数据结构与算法——线性表链式存储(双向循环链表)

今天总结线性表中的双向循环链表. 什么是双向循环链表? 看名字估计也就知道了,首相他是一个循环链表,也就是最后一个结点的指针域不为空,而是指向头结点,其次与单向循环链表相比,它是双向的.所谓双向,就是给每个结点再增加一个指针域,这个指针域指向前一个结点. 即是下面这样(来自百度图片): 为什么要用双向循环链表? 无论单链表还是单向循环链表,都只有一个指针域,它们都是直接指向后继结点的,如果要查找当前结点的后继结点,会很方便.但是如果给定一个结点,要得到它的前继结点,就会很麻烦,必须从第一个元素开

小猪的数据结构辅助教程——2.7 线性表中的双向循环链表

小猪的数据结构辅助教程--2.7 线性表中的双向循环链表 标签(空格分隔): 数据结构 本节学习路线图与学习要点 学习要点: 1.了解引入双向循环链表的原因 2.熟悉双向循环链表的特点以及存储结构 3.掌握双向循环链表的一些基本操作的实现逻辑 4.掌握逆序输出双向循环链表元素逻辑 1.双向循环链表的引入 2.双向循环链表的存储结构 双向循环链表的特点: 上面也说了,空间换时间,比起循环链表只是多了一个指向前驱的指针 特点的话: 判断空表:L ->next = L -> prior = L; 存

数据结构8: 双向链表(双向循环链表)的建立及C语言实现

之前接触到的链表都只有一个指针,指向直接后继,整个链表只能单方向从表头访问到表尾,这种结构的链表统称为 “单向链表”或“单链表”. 如果算法中需要频繁地找某结点的前趋结点,单链表的解决方式是遍历整个链表,增加算法的时间复杂度,影响整体效率.为了快速便捷地解决这类问题,在单向链表的基础上,给各个结点额外配备一个指针变量,用于指向每个结点的直接前趋元素.这样的链表被称为“双向链表”或者“双链表”. 双链表中的结点 双向链表中的结点有两个指针域,一个指向直接前趋,一个指向直接后继.(链表中第一个结点的

数据结构之双向链表(包含双向循环链表)

双向(循环)链表是线性表的链式存储结构的又一种形式. 在之前已经讲述了单向链表和循环链表.相比于单向链表只能从头结点出发遍历整个链表的局限性,循环链表使得可以从任意一个结点遍历整个链表. 但是,不管单向链表也好,循环链表也罢,都只能从一个方向遍历链表,即只能查找结点的下一个结点(后继结点),而不能查找结点的上一个结点(前驱结点).鉴于上述问题,引入了双向链表.由于双向循环链表包含双向链表的所有功能操作.因此,我们只讲述双向循环链表. 与单向链表不同,双向链表的结点构造如下图所示.即一个结点由三个

数据结构_线性表_链式存储_双向循环链表的基本操作

//双向链表,将头结点和尾结点链接起来,就构成了双向循环链表 //双向循环链表是将头结点的前驱指针指向了尾结点,同时将尾结点的后劲指针指向了头结点. //空表,头结点的前驱和后继指针均指向了自己,这也是判断双向循环链表是否为空的条件, //双向循环链表具有对称性 //缺点,是要付出空间代价的 双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱.所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点.一般我们都构造双向循环链表. 代

数据结构——栈和队列相关算法实现

数据结构栈和队列的基本算法实现 限定性线性表--栈 栈的定义 栈作为一种限定性的线性表,是将线性表的插入和删除操作限制为仅在表的一端进行. 基本算法演示 /* 栈的常见操作: 1.初始化栈 2.元素进栈 3.元素出栈 4.栈的遍历 5.判断栈是否为空栈 6.清空整个栈 */ # include <stdio.h> # include <stdlib.h> typedef struct Node { int date; struct Node * pNext; }NODE,* PNO

算法导论13:双向循环链表 2016.1.13

今天这个又打了很长时间,本来觉得数据结构就是那样,不过是一种思维,但是实际上真正自己打和想象中差距还是很大,需要考虑到各种细节. 今天这个问题有一个比较有意思的应用,就是“约瑟夫环问题”. 具体可以参见百度百科: http://baike.baidu.com/link?url=poA1Aanlptc6yzP1puYhSw_0RQjRAplhPfHwk6eoiqMNxw6WigCEbexxZ8a9SUbrMGokpPbKNzVYw308xjeEw_ 读完问题就可以发现,这个问题用链表就是一个很完美

010给定一个循环链表,实现一个算法返回这个环的开始结点 (keep it up)

给定一个循环链表,实现一个算法返回这个环的开始结点. 定义: 循环链表:链表中一个结点的指针指向先前已经出现的结点,导致链表中出现环. 例子: 输入:A -> B -> C -> D -> E -> C [结点C在之前已经出现过] 输出:结点C 可以用一个map<node*,bool> 就解决问题了. 下面是编程之美上一种奇特的解法:快慢指针解法. 代码: struct SNode { int data; SNode* next; }; SNode* findCi