双链表及其相关操作(C++)

双链表简要提点

  • 相比于单链表多引入的一个prior域用于指向前驱结点。
  • 更加利于删除或插入操作(不需要借助中间指针变量即可完成制定操作)。

C++代码实现

#include<iostream>
using namespace std;

typedef struct Node {   // 定义结点
    int date;
    struct Node *prior, *next;
}DNode, *DLinkList;

DLinkList initDList()       // 初始化链表
{
    DLinkList head = new DNode; // 创建头节点
    head->next = nullptr;   // 头节点的next域为空指针
    head->prior = nullptr;
    return head;
}

int isEmpty(DLinkList DL)       // 判断链表是否为空
{
    return DL->next == nullptr;
}

void back_insert(DLinkList L, int e)        // 在链表末尾插入元素
{
    DNode* q = new DNode;   // 为节点申请空间
    q->date = e;
    q->next = nullptr;
    if (L->next == nullptr)
    {
        L->next = q;
        q->prior = L;
    }
    else
    {
        DNode* p = L->next; // p初始化为头节点的next节点
        while (p->next != nullptr)
        {
            p = p->next;
        }
        p->next = q;    // 赋值
        q->prior = p;
    }
}

int getElemIndex(DLinkList L, int e)        // 查找某个元素所在位置
{
    DNode* p = L->next;     // 这里假设头节点的下标为0
    int i = 1;
    while (p)
    {
        if (p->date == e)   // 查找成功,则返回下标
            return i;
        p = p->next;
        i++;
    }
    cout << "Not exist!" << endl;
    return -1;
}

int getIndexElem(DLinkList L, int i)            // 求某个位置的元素
{
    DNode* p = L->next;
    int j = 0;
    while (p && ++j < i)
    {
        p = p->next;
    }
    if (!p || j > i)
    {
        cout << "Index Error!";
        return -1;
    }
    else
        return p->date;
}

void insert_after(DLinkList L, int index, int value)        // 在某位置之后插入元素
{
    DNode* p = L->next;
    DNode* q = new DNode;   // 创建一个临时节点
    q->date = value;
    int i = 0;
    while (p&& ++i < index)
    {
        p = p->next;
    }
    if (!p || i > index)
    {
        cout << "Index Error!";
    }
    q->prior = p;       // 先将q的prior域指向p
    q->next = p->next;  // 将q的next域指向p后继节点
    p->next->prior = q; // p后面的节点的prior域指向q
    p->next = q;        // p的next指向q
}

void insert_before(DLinkList L, int index, int value)       // 在某位置之前插入元素
{
    DNode* p = L->next;
    DNode* q = new DNode;   // 创建一个临时节点
    int i = 0;
    while (p&& ++i < index)
    {
        p = p->next;
    }
    if (!p || i > index)
    {
        cout << "Index Error!";
    }
    q->date = value;    
    q->prior = p->prior;    // 先将q的prior指向p的前驱结点
    q->next = p;        // q的next域指向p
    p->prior->next = q;     // p的前驱结点指向q
    p->prior = q;   // p的prior域指向q
}

void delete_node(DLinkList L, int index)        // 删除指定位置节点
{
    DNode* p = L->next;
    int j = 0;
    while (p && ++j < index)
    {
        p = p->next;
    }
    if (!p || j > index)
    {
        cout << "Index Error!";
    }
    p->prior->next = p->next;   // p的前驱结点的next域指向p的后继节点
    p->next->prior = p->prior;  // p的后继结点的prior域指向p的前驱结点
    delete p;       // 释放结点p
}

void print(DLinkList L)     // 显示链表内容
{
    DNode *p = L->next;
    cout << "Now the double linklist contents:" << endl;
    while (p)
    {
        cout << p->date << " ";
        p = p->next;
    }
    cout << endl;
}

int main()
{
    const int date[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
    DLinkList myDLinkList = new DNode;
    myDLinkList = initDList();
    if (isEmpty(myDLinkList))
        cout << "Empty list, now insert some values... " << endl;
    for (int i = 0;i < 9;i++)
    {
        back_insert(myDLinkList, date[i]);  // 依次在链表末尾插入元素
    }
    print(myDLinkList);
    cout << "The value 6's index is: " << getElemIndex(myDLinkList, 6) << endl;
    cout << "The index 6's value is: " << getIndexElem(myDLinkList, 6) << endl;
    cout << "Input a number inserting after 6: \n";
    int number;
    cin >> number;
    insert_after(myDLinkList, 6, number);
    print(myDLinkList);
    cout << "Input a number inserting before 6: \n";
    int number1;
    cin >> number1;
    insert_before(myDLinkList, 6, number1);
    print(myDLinkList);
    cout << "Input the index to delete: " << endl;
    int index;
    cin >> index;
    delete_node(myDLinkList, index);
    print(myDLinkList);

    delete myDLinkList;
    system("pause");
    return 0;
}

运行结果

Empty list, now insert some values...
Now the double linklist contents:
1 2 3 4 5 6 7 8 9
The value 6's index is: 6
The index 6's value is: 6
Input a number inserting after 6:
777
Now the double linklist contents:
1 2 3 4 5 6 777 7 8 9
Input a number inserting before 6:
555
Now the double linklist contents:
1 2 3 4 5 555 6 777 7 8 9
Input the index to delete:
7
Now the double linklist contents:
1 2 3 4 5 555 777 7 8 9

猜你喜欢

转载自blog.csdn.net/weixin_40170902/article/details/80595572