zoukankan      html  css  js  c++  java
  • 数据结构(复习)关于双向链表

    循环单链表的出现,虽然能够实现从任一结点出发沿着链能找到其前驱结点,但时间耗费是O(n)。如果希望从表中快速确定某一个结点的前驱,另一个解决方法就是在单链表的每个结点里再增加一个指向其前驱的指针域prior。这样形成的链表中就有两条方向不同的链,我们可称之为双(向)链表(Double Linked List)。双链表的结构定义如下:

    typedef struct DNode

    {

    ElemType data;

    struct DNode *prior,*next;

    }DNode,*DoubleList;

    双链表的结点结构如图2.14所示。

    与单链表类似,双链表一般也是有头指针唯一确定的,增加头结点也能使双链表的某些运算变得方便。同时双向链表也可以有循环表,称为双向循环链表,其结构如图2.15所示。

    由于在双向链表中既有前向链又有后向链,寻找任一个结点的直接前驱结点与直接后继结点变得非常方便。设指针p指向双链表中某一结点,则有下式成立:

    P->prior->next=p=p->next->prior

    在双向链表中,那些只涉及后继指针的算法,如求表长度、取元素、元素定位等,与单链表中相应的算法相同,但对于前插和删除操作则涉及到前驱和后继两个方向的指针变化,因此与单链表中的算法不同。

    1.双向链表的前插操作

    算法描述:欲在双向链表第i个结点之前插入一个新的结点,则指针的变化情况如图2.16所示。

    -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

    // 关于数据结构的总结与复习  Coding
    //3.关于双向循环链表的问题
    
    #include <cstdio>
    #include <cstdlib>
    #define error 0
    #define ok 1
    //#define _OJ_
    
    typedef struct Lnode
    {
        int data;
        struct Lnode *pre;
        struct Lnode *next;         //定义前驱和后继
    } Lnode, *Linklist;
    
    Linklist
    Init_List(void)
    {
        int i, n;
        Linklist L, head, p;
        L = (Linklist) malloc (sizeof(Lnode));
        head = L;
        
        scanf("%d", &n);
        for (i = 0; i < n; i++) {
        p = (Linklist) malloc (sizeof(Lnode));    scanf("%d", &p->data);
        L->next = p;    p->pre = L;
        L = p;
        }
        L->next = head;    head->pre = L;         //前后相邻元素互指,  最后元素指向head,
        //head指向tail
        return head;
    }
    
    int
    List_Length(Linklist L)
    {
        int cnt = 0;
        Linklist p;
        p = L;
    
        while (p->next != L) {
              cnt++;
              p = p->next;
        }
        return cnt;
    }
    
    int
    List_Delete(Linklist L, int i)
    {
        int j;
        Linklist p;
        p = L->next;
    
        if(i < 1 && i > List_Length(L)) {
            printf("删除超限:
    ");    return error;
        }
    
        printf("从第%d个元素删除:
    ", i);
        for (j = 1; j < i; j++) {
            p = p->next;
        }//值得注意的是单链表删除,插入找到前驱即可,,而在这里要找到第i个元素
    
        p->pre->next = p->next;
        p->next->pre = p->pre;
    }
    
    
    int
    List_Insert(Linklist L, int i, int e)
    {
        int j;
        Linklist p, s;
        p = L->next;
        s = (Linklist) malloc (sizeof(Lnode));    s->data = e;
    
        if(i < 1 && i > List_Length(L) + 1) {
            printf("插入超限:
    ");     return error;
        }
    
        for (j = 1; j < i; j++) {
            p = p->next;
        }//值得注意的是单链表删除,插入找到前驱即可,,而在这里要找到第i个元素
    
        s->pre = p->pre;    p->pre->next = s;
        s->next = p;        p->pre = s;
    }
    
    void
    print(Linklist L)
    {
        Linklist p;
        p = L;
        printf("打印循环链表:");
        while (p->next != L) {
            printf("%d ", p->next->data);
            p = p->next;
        }
    }
    
    void
    print1(Linklist L)
    {
        Linklist p;
        p = L;
        printf(" 逆向打印循环链表:");
        while (p->pre != L) {
            printf("%d ", p->pre->data);
            p = p->pre;
        }
    }
    
    
    int main(int argc, char const *argv[]) {
    #ifndef _OJ_ //ONLINE JUDGE
           freopen("input.txt", "r", stdin);
           //freopen("output.txt", "w", stdout);
    #endif
        
    
        Linklist L;
    
        L = Init_List();
    
        print(L);
    
        printf("
    双向循环链表长度:%d
    ", List_Length(L));
    
        List_Delete(L, 2);
    
        // List_Delete(L, 1);
    
        // List_Delete(L, 3);               //边界值的测试
    
        print(L);
    
        // List_Insert(L, 2, 10);
    
        // List_Insert(L, 1, 11);
    
        List_Insert(L, 4, 12);             //边界值得测试
    
        print1(L);
        
        return 0;
    }
    

      

  • 相关阅读:
    Silverlight应用小知识点
    svn如何给新文件加锁
    sql统计上周销售量的起止时间
    sql中null 和 ‘’(空字符串)
    蓝桥杯 算法训练 操作格子 [ 线段树 ]
    90分 蓝桥杯 算法提高 道路和航路 [ 最短路 ]
    蓝桥杯 算法训练 安慰奶牛 [ 最小生成树 ]
    蓝桥杯 算法提高 金属采集 [ 树形dp 经典 ]
    转 蓝桥杯 历届试题 大臣的旅费 [ dfs 树的直径 ]
    蓝桥杯 算法训练 最短路 [ 最短路 bellman ]
  • 原文地址:https://www.cnblogs.com/airfand/p/5060709.html
Copyright © 2011-2022 走看看