双向链表的重要操作源码

// 双向链表.cpp : 定义控制台应用程序的入口点。
//带头结点的双向链表
#include "stdafx.h"
#include "malloc.h"
typedef int DataType;//宏定义:便于更改数据类型,提高程序复用性

/*定义双链表的结点类型,整个部分的实质就是用户自定义数据类型*/
/*系统并不为Node整体分配内存空间,内存空间实际上是变量所占内存空间之和*/
/*优点:真正的动态,不需要处理固定容量的问题;缺点:相比顺序表而言丧失了随机存取的能力*/
typedef struct Node {
    DataType data;//定义数据域变量
    struct Node *prior;//定义前驱指针
    struct Node *next;//定义后继指针
}DNode,* PDNode,* DLinkList;//DNde和*PDNode都是代表Struct Node数据类型,其区别在于:前者表示类型名,而后者表示指向Struct Node数据类型的指针

/*创建双向链表:*/

/*头插法创建双向链表:直接使得头结点的前驱结点和后继结点指向头结点*/
/*DLinkList Create_DLinkList(DLinkList &h)
{
    DLinkList p;
    DataType data;
    h = (DLinkList)malloc(sizeof(DNode));
    h->prior = NULL;
    h->next =h;
    printf("input the value of data:\n");
    scanf_s("%d",&data);
    while (data!=0)
    {
        p= (DLinkList)malloc(sizeof(DNode));
        p->data = data;
        p->next = h->next;
        p->prior = h;
        h->next = p;
        h->prior = h;
        printf("input the value of new data:\n");
        scanf_s("%d",&data);
    }
    return h;
}*/

/*尾插法创建双向链表:*/
DLinkList Create_RDLinkList(DLinkList &h)
{
    DLinkList p,r;
    DataType data;
    //创建头结点
    h = (DLinkList)malloc(sizeof(DNode));
    h->prior = h;
    h->next = h;
    r = h->next;
    printf("input the data:\n");
    scanf_s("%d",&data);
    while (data!=0)
    {
        //创建新的结点
        if (!(p = (DLinkList)malloc(sizeof(DNode))))
            return NULL;
        p->data = data;
        r->next = p;
        p->prior =r;
        r = p;
        printf("input the value of new data:\n");
        scanf_s("%d", &data);
    }
    r->next = NULL;
    return h;
}
 /*遍历双向链表:通过右移指针,直到指针域为空*/
DLinkList TraverseList(DLinkList h)//h为指向链表的头指针
{
    PDNode p = h->next;//将头指针指向第一个结点                  
    while (p !=NULL)
    {
        printf("%d \t", p->data);
        p = p->next;//右移指针
    }
    printf("\n");
    return h;
}//时间复杂度为o(1)
/*插入:1)算法思想:1.将待插入点的前驱指针指向p的前驱结点:q->prior=p->prior;
                     2.将p前驱结点的后继指针指向新结点q:p->prior->next=q;
                     3.将p的前驱指针指向q:p->prior=q;
                     4.将q的后继指向p:q->next=p;
        2)时间复杂度:o(1):
                     */
int ListInsert(DLinkList &h, int pos, DataType item)//h为指向双向链表的指针,pos为插入位置,item为待插入的数据元素
{
    PDNode p = h->next,q;//p指向第一个结点
    int j=0;
    while (p!=NULL && j < pos-1)//若指针不是头指针且没有超过插入位置坐标,执行此循环,否则退出
    {
        p = p->next;//指针右移,寻找待插入点
        j++;
    }
    if (pos<1 || j !=pos-1)//当指针指向头指针,或者位置大于插入位置坐标时
    {
        printf("插入位置不合法!\n");
        return 0;//返回类型
    }
if(!(q = (PDNode)malloc(sizeof(DNode))))//为新结点动态分配内存空间,q为指向新结点的指针,PDNode为新结点指针,DNode为链表
    return 0;
    q->data = item;//给数据域赋值
    q->prior = p->prior;//将p的前驱指针给q的前驱指针
    p->prior->next = q;//将p的前驱结点的后继指针指向q
    q->next = p;//将q的后继指针指向p
    p->prior = q;//将p的前驱指针指向q
    return 1;
}
/*删除某个位置上的元素:1.先移动指针找到位置;2.s=p;3.p->prior->next=p->next;4.p->next->prior=p->prior;5.free(s)
时间复杂度:o(1)
优缺点:*/
DLinkList Del_DLinkList(DLinkList &h, int i)
{
    DLinkList p=h->next,s;
    DataType j=0;
    while (p!=NULL && j<i-1)
    {
        j++;
        p = p->next;
    }
    if (i<1 || j !=i-1)
    {
        printf("删除的位置不合法");
    }
    s = p;
    p->prior->next = p->next;
    p->next->prior = p->prior;
    free(s);
    return h;
}
int main()
{
    DLinkList h;//使头结点为空
    Create_RDLinkList(h);
    printf("插入操作前双向链表的数据元素:\n");
    TraverseList(h);
    printf("插入操作后双向链表的数据元素:\n");
    ListInsert(h,2,100);
    TraverseList(h);
    Del_DLinkList(h, 4);
    TraverseList(h);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_32962773/article/details/82828182