双向链表

来源:互联网 发布:mac能打开mpq文件吗 编辑:程序博客网 时间:2024/05/17 04:24

双向链表

      在线性链式存储结构的结点中只有一个指示直接后继的指针域,由此,从某个结点出发只能顺指针往后寻查其他结点。若要寻查结点的直接前趋,则需从表头指针出发。换句话说,在单链表中,NextElem的执行时间是o(1),而PriorElem的执行时间为O(n)。为克服单链表这种单向性的缺点,可利用双向链表。

实现代码:

//双链循环线性表的表示与实现#include <stdio.h>#include <stdlib.h>/******************************************************************************/* 数据类型和常量定义/******************************************************************************/#define TURE         1#define FALSE        0#define OK           1#define ERROR        0#define OVERFLOW    -2typedef int Status;typedef int ElemType;/******************************************************************************/* 数据结构声明/******************************************************************************//* 线性表的双向链表存储结构 */typedef struct DuLNode {    ElemType data;    struct DuLNode *prior;    struct DuLNode *next;} DuLNode, *DuLinkList;//初始化双链循环线性表Status InitList_DuL(DuLinkList &L) {    L = (DuLinkList)malloc(sizeof(DuLNode));    L->next = L->prior = L;    return OK;}//获取双链循环线性表中的元素DuLNode * GetElemP_Dul(DuLinkList L, int i) {    int j;    struct DuLNode *p = L;    if (i < 1)   //非法i值        return NULL;    if (p->next == L) //空双向循环链表        return L;    p = L->next; j = 1;   //初始化, p指向第一个结点, j为计数器    while(p != L && j < i) {  //顺指针向后查找, 直到p指向第i个元素或p指向头结点        p = p->next; ++j;    }    return p;}//插入元素Status ListInsert_DuL(DuLinkList &L, int i, ElemType e) {    //在带头结点的双链循环线性表L中第i个位置之前插入元素e    //i的合法值为1 <= i <= 表长 + 1    struct DuLNode *p = NULL;    struct DuLNode *s = NULL;    if (!(p = GetElemP_Dul(L, i)))        return ERROR;    if(!(s = (DuLinkList)malloc(sizeof(DuLNode)))) return ERROR;    s->data = e;    s->prior = p->prior; p->prior->next = s;    s->next = p;         p->prior = s;    return OK;}//删除元素Status ListDelete_DuL(DuLinkList &L, int i, ElemType &e) {    //在带头结点的双链线性表L中, 删除第i个元素, 并由e返回其值    //i的合法值为1 <= i <= 表长    struct DuLNode *p = NULL;    if (!(p = GetElemP_Dul(L, i)) || L == GetElemP_Dul(L, i))        return ERROR;    e = p->data;    p->prior->next = p->next;    p->next->prior = p->prior;    free(p); return OK;}//遍历线性表Status ListTraverse_DuL(DuLinkList &L, Status (*Visit)(ElemType)) {    printf("traverse list: ");    struct DuLNode *p = L->next; //略过头结点    while (p != L) {        Visit(p->data);        p = p->next;    }    return OK;}//访问线性表中的元素Status Visit(ElemType e){    printf("%d ", e);    return OK;}//测试函数void main(){    DuLinkList L;  ElemType e;    InitList_DuL(L);        //插入元素    if (OK == ListInsert_DuL(L, 0, 55)) printf("insert 55 succeed!\n");    if (OK == ListInsert_DuL(L, 1, 56)) printf("insert 56 succeed!\n");    ListTraverse_DuL(L, Visit); printf("\n");    if (OK == ListInsert_DuL(L, 2, 57)) printf("insert 57 succeed!\n");    if (OK == ListInsert_DuL(L, 1, 58)) printf("insert 58 succeed!\n");    ListTraverse_DuL(L, Visit); printf("\n");    //删除元素    if (OK == ListDelete_DuL(L, 1, e)) printf("the %dst elem deleted!\n", 1);    if (OK == ListDelete_DuL(L, 3, e)) printf("the %drd elem deleted!\n", 3);    if (OK == ListDelete_DuL(L, 4, e))         printf("the %dth elem deleted!\n", 4);    else        printf("delete the %dth elem failed!\n", 4);    if (OK == ListDelete_DuL(L, 1, e)) printf("the %dst elem deleted!\n", 1);    ListTraverse_DuL(L, Visit); printf("\n");    if (OK == ListDelete_DuL(L, 1, e)) printf("the %dst elem deleted!\n", 1);    ListTraverse_DuL(L, Visit); printf("\n");}


原创粉丝点击