数据结构复习之双向链表

双向链表和单链表的主要区别是双链表每个节点有两个指针域, 分别指向前一个节点和后一个节点.

#include<iostream>
using namespace std;

struct DoubleLNode{
    int data;
    struct DoubleLNode *prior;
    struct DoubleLNode *next;
};

DoubleLNode* DoubleLNodeInit();
void addTail(DoubleLNode *L, int data);
void addHead(DoubleLNode *L, int data);
bool isEmpty(DoubleLNode *L);
bool DoubleLNodeInsert(DoubleLNode *L, int i, int data);
bool DoubleLNodeDelete(DoubleLNode *L, int i, int &data);
int getLength(DoubleLNode *L);

// 初始化链表
DoubleLNode* DoubleLNodeInit(){
    DoubleLNode *L;
    L = (DoubleLNode *)malloc(sizeof(DoubleLNode));
    L->data = 0;
    L->next = NULL;
    L->prior = NULL;
    return L;
}

// 尾插法
void addTail(DoubleLNode *L, int data){
    DoubleLNode *p, *q = L;
    p = (DoubleLNode *)malloc(sizeof(DoubleLNode));
    while(q->next != NULL){
        q = q->next;
    }
    p->data = data;
    p->prior = q;
    p->next = q->next;
    q->next = p;
}

// 头插法
void addHead(DoubleLNode *L, int data){
    DoubleLNode *p, *q = L;
    p = (DoubleLNode *)malloc(sizeof(DoubleLNode));
    // 注意当是空表时需要特殊处理
    if (isEmpty(q)){
        p->data = data;
        p->prior=q;
        p->next = q->next;
        q->next = p;
    }else {
        p->data = data;
        p->prior = q;
        p->next = q->next;
        q->next->prior = p;
        q->next = p;
    }
}

// 在第i个元素位置插入值为data的节点
bool DoubleLNodeInsert(DoubleLNode *L, int i, int data){
    if (getLength(L) < i || i <= 0) return false;
    DoubleLNode *p, *q = L;
    p = (DoubleLNode *)malloc(sizeof(DoubleLNode));
    int count = 0;
    while(count < i){
        q = q->next;
        count++;
    }
    p->data = data;
    p->next = q;
    p->prior = q->prior;
    q->prior->next = p;
    q->prior = p;
    return true;
}

// 删除位置i的节点,并把第i个节点的data保存在data中
bool DoubleLNodeDelete(DoubleLNode *L, int i, int &data){
    if (getLength(L) < i || i <= 0) return false;
    DoubleLNode *q = L;
    int count = 0;
    while(count < i){
        q = q->next;
        count++;
    }
    data = q->data;
    if (i != getLength(L)){
        q->prior->next = q->next;
        q->next->prior = q->prior;
        delete q;
    }else {
        q->prior->next = q->next;
        delete q;
    }
    return true;
}

// 打印链表
void show(DoubleLNode *L){
    cout << "head";
    L = L->next;
    while(L != NULL){
        cout << "->" << L->data;
        L = L->next;
    }
}

// 判断是否为空
bool isEmpty(DoubleLNode *L){
    if (L->next == NULL && L->prior == NULL) return true;
    return false;
}

// 获取链表长度
int getLength(DoubleLNode *L){
    int length = 0;
    L = L->next;
    while(L != NULL){
        length++;
        L = L->next;
    }
    return length;
}

int main(){
    DoubleLNode *L1 = DoubleLNodeInit();
    DoubleLNode *L2 = DoubleLNodeInit();
    
    cout << "分别以尾插法和头插法分别向两个双向链表插入1-5五个节点" << endl;
    for (int i = 1; i <= 5; i++){
        addTail(L1, i);
        addHead(L2, i);
    }
    
    cout << "L1:";
    show(L1);
    cout << endl;
    cout << "L1的长度:";
    cout << getLength(L1) << endl;
    cout << "L2:";
    cout << "L2的长度:";
    cout << getLength(L2) << endl;
    show(L2);
    cout << endl;
    
    cout << "在L1第三个节点处插入7" << endl;
    if (DoubleLNodeInsert(L1, 3, 7)){
        cout << "插入成功!L1:";
        show(L1);
        cout << endl;
    }else cout << "插入失败!" << endl;
    
    cout << "删除L1第6个节点" << endl;
    int item = 0; // 删除节点的值
    if (DoubleLNodeDelete(L1, 6, item)){
        cout << "删除成功!删除的节点的data是" << item << endl;
        cout << "L1:";
        show(L1);
        cout << endl;
    }else {
        cout << "删除失败!" << endl;
    }
    return 0;
}

运行结果

 

分别以尾插法和头插法分别向两个双向链表插入1-5五个节点
L1:head->1->2->3->4->5
L1的长度:5
L2:L2的长度:5
head->5->4->3->2->1
在L1第三个节点处插入7
插入成功!L1:head->1->2->7->3->4->5
删除L1第6个节点
删除成功!删除的节点的data是5
L1:head->1->2->7->3->4
Program ended with exit code: 0

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值