双向链表的重要操作源码

// 双向链表.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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
码,经典。 CARD *myinsert(LCARD *head, LCARD *insert) { LCARD *temp = NULL; if (head==NULL)//链表为空 { head = insert; insert->next = insert; insert->prior = insert; } else//链表非空 { temp = head; if (head->cardnum>insert->cardnum)//插入到头前边,并且把自己当作头 { head->prior->next = insert; insert->prior = head->prior; insert->next = head; head->prior = insert; head = insert; } if (insert->cardnum0<50)//小于50正向插入 { while ((temp->cardnum<insert->cardnum)&&(temp->next!=head))//循环 { temp = temp->next; } if (temp->cardnum>insert->cardnum)//第一个条件终止的 { temp->prior->next = insert; insert->prior = temp->prior; insert->next = temp; temp->prior = insert; } else//第二个条件终止的 { head->prior->next = insert; insert->prior = head->prior; insert->next = head; head->prior = insert; } } else//大于50反向插入 { while ((temp->cardnum>insert->cardnum)&&(temp->prior!=head))//循环,第二个条件禁止跑飞 { temp = temp->prior; } if (temp->cardnum<insert->cardnum)//只有第一个条件可以终止的 { temp->next->prior = insert; insert->next = temp->next; insert->prior = temp; temp->next = insert; } } } //printf("%d\t%d\n", insert->id, insert->cardnum); return head; } void swap_id(SWID *sw) { LCARD *temp = sw->head; if (sw->head->cardnum==sw->swapcardnum) { printf("out person cardnum=%d\n", sw->head->id); sw->head->id = sw->inID; return ; } if ((sw->swapcardnum0)<50) { while ((temp->cardnum!=sw->swapcardnum)&&(temp->next!=sw->head)) { temp = temp->next; } if (temp->cardnum==sw->swapcardnum) { printf("out person cardnum=%d\n", sw->head->id); temp->id = sw->inID; } } else { while ((temp->cardnum!=sw->swapcardnum)&&(temp->prior!=sw->head)) { temp = temp->prior; } if (temp->cardnum==sw->swapcardnum) { printf("out person cardnum=%d\n", sw->head->id); temp->id = sw->inID; } } } LCARD *mydel(LCARD *head, LCARD *del) { LCARD *temp = NULL; if (head==NULL)//没有链表 { printf("there is no card\n"); } else//有链表 { if(head->next==head)//链表里就有一个节点并且为头结点 { if (head->cardnum==del->cardnum) { free(head); head = NULL; } else { printf("in mydel error\n"); } } else//链表里有超过一个的节点 { temp = head; if (del->cardnum0<50)//成立则正向删除 { while ((temp->cardnum!=del->cardnum)&&(temp->next!=head)) { temp = temp->next; } if (temp->cardnum==del->cardnum) { temp->prior->next = temp->next; temp->next->prior = temp->prior; free(temp); } } else//反向删除 { while ((temp->cardnum!=del->cardnum)&&(temp->prior!=head)) { temp = temp->prior; } if (temp->cardnum==del->cardnum) { temp->prior->next = temp->next; temp->next->prior = temp->prior; free(temp); } } } } return head; }

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值