C++双向链表(插入/删除/打印)

1.引入 + 建立结构体        

        双向链表基于单向链表,由只能指向next或者previous节点变为可以同时知道前后两个节点的存在。

双向链表

因此可以同时创建两个指针,指向头部的head和指向尾部的tail去帮助后边的遍历。

struct Node {
    int data;
    Node* next;
    Node* prev;
};

Node* head = NULL;
Node* tail = NULL;

2.实现头插和尾插

Node* CreateNode(int n) {//创建首尾指向空的节点
    Node* tmp = new Node();
    tmp->data = n;
    tmp->next = NULL;
    tmp->prev = NULL;
    return tmp;
}

void InsertHead(int x) {
    Node* temp = CreateNode(x);
    if (head == NULL) {
        head = temp;
        tail = temp;
    }
    temp->next = head;
    head->prev = temp;
    head = temp;
}

void InsertTail(int y) {
    Node* temp = CreateNode(y);
    if (tail == NULL) {
        head = temp;
        tail = temp;
    }
    tail->next = temp;
    temp->prev = tail;
    tail = temp;
}

3.正向和反向打印链表

void Print() {
    Node* p = head;
    while (p != NULL) {
        cout << p->data;
        p = p->next;
    }
    cout << endl;
}

void ReversePrint() {
    Node* q = tail;
    while (q != NULL) {
        cout << q->data;
        q = q->prev;
    }
    cout << endl;
}

4.删除链表中的节点

//假设删除目标为x。
//将x-1的尾部指针指向x+1;将x+1的头部指针指向x-1。
//最后将x delete。

void ChangePtr(Node* ptr) {
    if (ptr->prev != NULL) {
        ptr->prev->next = ptr->next;
    }
    else {
        head = ptr->next;
    }

    if (ptr->next != NULL) {
        ptr->next->prev = ptr->prev;
    }
    else {
        tail = ptr->prev;
    }

}

void Delete(int x) {
    Node* tmp = head;
    Node* tmp1 = tail;
    //搜索用了两个指针,为了快一点
    while (tmp != NULL && tmp1 != NULL) {
        if (tmp->data == x) {
            ChangePtr(tmp);
            delete(tmp);//记得new用delete!!不是free!
            return;
        }
        else if (tmp1->data == x) {
            ChangePtr(tmp1);
            delete(tmp1);
            return;
        }
        tmp = tmp->next;
        tmp1 = tmp1->prev;
    }
}

5.整体代码

/*
*******************************************
* 
* 项目:双向链表/ Double Linked List
* 结构体--Node(拥有prev,next两个指针)
* 全局变量:
* head:指向头部
* tail:指向尾部
* 
*******************************************
* 
* CreateNode():创建一个首位地址=0的节点
* InsertHead():头部插入节点
* InsertTail():尾部插入节点
* 
*******************************************
* 
* Delete():删除节点(传入要删除的data)
* -ChangePtr():将目标节点(要删的那个)的前后节点建立联结
* 
*******************************************
* 
* Print():打印链表(正向)
* ReversePrint():打印链表(反向)
* 
*******************************************
*/
#include <iostream>
using namespace std;

struct Node {
    int data;
    Node* next;
    Node* prev;
};

Node* head = NULL;
Node* tail = NULL;

Node* CreateNode(int n) {
    Node* tmp = new Node();
    tmp->data = n;
    tmp->next = NULL;
    tmp->prev = NULL;
    return tmp;
}

void InsertHead(int x) {
    Node* temp = CreateNode(x);
    if (head == NULL) {
        head = temp;
        tail = temp;
    }
    temp->next = head;
    head->prev = temp;
    head = temp;
}

void InsertTail(int y) {
    Node* temp = CreateNode(y);
    if (tail == NULL) {
        head = temp;
        tail = temp;
    }
    tail->next = temp;
    temp->prev = tail;
    tail = temp;
}

void ChangePtr(Node* ptr) {
    if (ptr->prev != NULL) {
        ptr->prev->next = ptr->next;
    }
    else {
        head = ptr->next;
    }

    if (ptr->next != NULL) {
        ptr->next->prev = ptr->prev;
    }
    else {
        tail = ptr->prev;
    }

}

void Delete(int x) {
    Node* tmp = head;
    Node* tmp1 = tail;

    while (tmp != NULL && tmp1 != NULL) {
        if (tmp->data == x) {
            ChangePtr(tmp);
            delete(tmp);//记得new用delete!!
            return;
        }
        else if (tmp1->data == x) {
            ChangePtr(tmp1);
            delete(tmp1);
            return;
        }
        tmp = tmp->next;
        tmp1 = tmp1->prev;
    }
}

void Print() {
    Node* p = head;
    while (p != NULL) {
        cout << p->data;
        p = p->next;
    }
    cout << endl;
}

void ReversePrint() {
    Node* q = tail;
    while (q != NULL) {
        cout << q->data;
        q = q->prev;
    }
    cout << endl;
}

int main()
{
    InsertHead(2);
    InsertTail(4);
    InsertHead(6);
    InsertTail(8);
    InsertTail(3);
    Print();
    ReversePrint();
    Delete(8);
    Print();
    ReversePrint();
}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值