数据结构——Doubly_Linked_List的代码实现

Reference Book: 《Data Structure and Program Design in C++》

------------------------------------------------------------------------------------------------------------------------------------------------

1. (1) Node.h文件

#ifndef NODE_H_INCLUDED
#define NODE_H_INCLUDED

template <class Node_entry>
struct Node
{
    // data members
    Node_entry entry;
    Node<Node_entry> *next;
    Node<Node_entry> *back;

    // constructors
    Node();
    Node(Node_entry item, Node<Node_entry> *link_back = nullptr,
                          Node<Node_entry> *link_next = nullptr);
                // The parameter add_on is set an default value null.
};

#endif // NODE_H_INCLUDED

1. (2) Node.cpp文件

#include "Node.h"

template <class Node_entry>
Node<Node_entry>::Node()
/*Pre:None.
  Post:Initialize the next links to Null.
*/
{
    back = nullptr;
    next = nullptr;
}

template <class Node_entry>
Node<Node_entry>::Node(Node_entry item, Node<Node_entry> *link_back,
                                        Node<Node_entry> *link_next)
/*Pre:None.
  Post:Add a first node to Node structure.
*/
{
    entry = item;
    back = link_back;
    next = link_next;
}

2. (1) Doubly_Linked_List.h文件

/**********************************
        Doubly_Ordered_List
**********************************/

#ifndef DOUBLY_LINKED_LIST_H
#define DOUBLY_LINKED_LIST_H

#include "Node.h"

namespace
{
    enum Error_code{success, range_error, underflow, overflow, fail, not_present};
}

template <class List_entry>
class Doubly_Linked_List
{
    public:
        Doubly_Linked_List();
        int size()const;
        bool full()const;
        bool empty()const;
        void clear();
        void traverse(void(*visit)(List_entry &));
        Error_code retrieve(int position, List_entry &x)const;
        Error_code replace(int position, const List_entry &x);
        Error_code remove(int position, List_entry &x);
        Error_code insert(int position, const List_entry &x);

        ~Doubly_Linked_List();
        Doubly_Linked_List(const Doubly_Linked_List<List_entry> &copy);
        void operator = (const Doubly_Linked_List<List_entry> &copy);

    protected:
        Node<List_entry> *head;
        int count;

        mutable int current_position;   // 在const函数中需要修改用mutable
        mutable Node<List_entry> *current;
        void set_position(int position)const;

    private:
};



/*
    Implementation of the Class
*/

template <class List_entry>
Doubly_Linked_List<List_entry>::Doubly_Linked_List()
// 构造函数
{
    count = 0;
    head = current = nullptr;
    current_position = -1;
}

template <class List_entry>
Doubly_Linked_List<List_entry>::~Doubly_Linked_List()
// 析构函数
{
    clear();
}

template <class List_entry>
Doubly_Linked_List<List_entry>::Doubly_Linked_List(const Doubly_Linked_List<List_entry> &copy)
// 拷贝构造函数
{
    count = copy.count;
    current_position = copy.current_position;
    Node<List_entry> *new_node, *old_node = copy.head;

    if(old_node==nullptr)head = current = nullptr;
    else
    {
        new_node = head = new Node<List_entry>(old_node->entry);
        while(old_node->next != nullptr)
        {
            old_node = old_node->next;
            new_node->next = new Node<List_entry>(old_node->entry);
            new_node->next->back = new_node;
            new_node = new_node->next;
        }
        set_position(current_position);
    }
}

template <class List_entry>
void Doubly_Linked_List<List_entry>::operator = (const Doubly_Linked_List<List_entry> &copy)
// 操作符=重载
{
    if(this==&copy)return;  // 判断是否进行了自己赋值给自己的操作

    //Doubly_Linked_List new_copy(copy);  // 调用拷贝构造函数
    clear();
    Node<List_entry> *p = copy.head;
    int pos = 0;
    insert(pos, p->entry);  // 插入第一个元素并设置head指针
    head = current;
    if(p->next)p->next->back = p;
    p = p->next;
    pos++;
    while(p)
    {
        insert(pos, p->entry);
        if(p->next)p->next->back = p;   // p->next不为空时其back指针指向p所指的结点
        p = p->next;
        pos++;
    }

    count = copy.count;
    current_position = copy.current_position;
    // 不能直接用current = copy.current, 因为copy将被析构
    set_position(current_position);
}

template <class List_entry>
int Doubly_Linked_List<List_entry>::size()const
{
    return count;
}

template <class List_entry>
bool Doubly_Linked_List<List_entry>::full()const
{
    return false;
}

template <class List_entry>
bool Doubly_Linked_List<List_entry>::empty()const
{
    return (count<=0);
}

template <class List_entry>
void Doubly_Linked_List<List_entry>::clear()
{
    Node<List_entry> *p = head;
    for(; p!=nullptr; p = head)
    {
        head = head->next;
        delete p;
    }
    count = 0;
    head = current = nullptr;
    current_position = -1;
}

template <class List_entry>
void Doubly_Linked_List<List_entry>::set_position(int position)const
{
    // 向后搜索
    if(current_position <= position)
        for(; current_position != position; current_position++)
            current = current->next;
    // 向前搜索
    else
        for(; current_position != position; current_position--)
            current = current->back;
}

template <class List_entry>
Error_code Doubly_Linked_List<List_entry>::replace(int position, const List_entry &x)
{
    if(position<0 || position>=count)return range_error;
    set_position(position);
    current->entry = x;
    return success;
}

template <class List_entry>
Error_code Doubly_Linked_List<List_entry>::retrieve(int position, List_entry &x)const
{
    if(position<0 || position>=count)return range_error;
    set_position(position);
    x = current->entry;
    return success;
}

template <class List_entry>
Error_code Doubly_Linked_List<List_entry>::remove(int position, List_entry &x)
{
    Node<List_entry> *previous, *following;
    //if(count==0)return fail;
    if(position<0 || position>=count)return range_error;
    if(position==0)
    {
        following = head;
        current = head = head->next;    // 重设current和head指针
        current_position = 0;
        if(head)head->back = nullptr;   // 若还有结点将其back置为nullptr
    }
    else    // 包括了pos在count-1的情况
    {
        set_position(position-1);
        previous = current;
        following = current->next;
        previous->next = following->next;
        if(following->next)following->next->back = previous;
    }
    x = following->entry;
    delete following;
    count--;
    return success;
}

template <class List_entry>
Error_code Doubly_Linked_List<List_entry>::insert(int position, const List_entry &x)
{
    Node<List_entry> *new_node, *following, *preceding;
    if(position<0 || position>count)return range_error;
    // 在pos==0处进行插入
    if(position==0)
    {
        if(count==0)following = nullptr;
        else
        {
            set_position(0);
            following = current;
        }
        preceding = nullptr;
    }
    else
    {
        set_position(position-1);
        preceding = current;
        following = current->next;
    }
    new_node = new Node<List_entry>(x, preceding, following);   // 申请新结点
    if(new_node==nullptr)return overflow;   // 申请失败
    if(preceding!=nullptr)preceding->next = new_node;
    if(!preceding)head = new_node;  // 若在pos==0的位置插入重设head指针
    if(following!=nullptr)following->back = new_node;
    current = new_node;
    current_position = position;
    count++;
    return success;
}

template <class List_entry>
void Doubly_Linked_List<List_entry>::traverse(void (*visit)(List_entry &))
{
    Node<List_entry> *to_visit = head;
    for(; to_visit; to_visit = to_visit->next)  // 遍历列表中所有元素并执行visit函数
        (*visit)(to_visit->entry);
}
#endif // DOUBLY_LINKED_LIST_H


对下面代码每一步含义进行注释 def convert_to_doubly_linked_list(self): if not self.root: return None def convert(root): if not root.left and not root.right: return ListNode(root.val) if not root.left: right_head = convert(root.right) right_tail = right_head while right_tail.next: right_tail = right_tail.next cur_node = ListNode(root.val, None, right_head) right_head.prev = cur_node return cur_node if not root.right: left_tail = convert(root.left) left_head = left_tail while left_head.prev: left_head = left_head.prev cur_node = ListNode(root.val, left_tail, None) left_tail.next = cur_node return cur_node left_tail = convert(root.left) right_head = convert(root.right) left_head = left_tail while left_head.prev: left_head = left_head.prev right_tail = right_head while right_tail.next: right_tail = right_tail.next cur_node = ListNode(root.val, left_tail, right_head) left_tail.next = cur_node right_head.prev = cur_node return left_head return convert(self.root) def inorder_traversal(self, root): if not root: return self.inorder_traversal(root.left) print(root.val, end=' ') self.inorder_traversal(root.right) def print_bst(self): self.inorder_traversal(self.root) print() def traverse_doubly_linked_list(self, head): cur_node = head while cur_node: print(cur_node.val, end=' ') cur_node = cur_node.next print() def reverse_traverse_doubly_linked_list(self, head): cur_node = head while cur_node.next: cur_node = cur_node.next while cur_node: print(cur_node.val, end=' ') cur_node = cur_node.prev print()
06-12
这段代码是一个二叉搜索树(BST)转化为双向链表的函数,同时提供了打印BST和遍历双向链表的函数。 - `def convert_to_doubly_linked_list(self):`:定义一个将BST转化为双向链表的函数。 - `if not self.root:`:如果BST为空,则返回None。 - `def convert(root):`:定义一个递归函数,将BST转化为双向链表。 - `if not root.left and not root.right:`:如果该节点没有左右子树,返回一个只包含该节点值的ListNode。 - `if not root.left:`:如果该节点没有左子树,将右子树转化为双向链表,并将节点值作为新的头结点,返回该节点。 - `if not root.right:`:如果该节点没有右子树,将左子树转化为双向链表,并将节点值作为新的尾结点,返回该节点。 - `left_tail = convert(root.left)`:将左子树转化为双向链表,并返回左子树的尾结点。 - `right_head = convert(root.right)`:将右子树转化为双向链表,并返回右子树的头结点。 - `left_head = left_tail`:将左子树的头结点设置为左子树的尾结点。 - `while left_head.prev:`:找到左子树双向链表的头结点。 - `right_tail = right_head`:将右子树的尾结点设置为右子树的头结点。 - `while right_tail.next:`:找到右子树双向链表的尾结点。 - `cur_node = ListNode(root.val, left_tail, right_head)`:创建一个新的节点,值为当前节点值,左指针指向左子树双向链表的尾结点,右指针指向右子树双向链表的头结点。 - `left_tail.next = cur_node`:将左子树双向链表的尾结点的右指针指向新节点。 - `right_head.prev = cur_node`:将右子树双向链表的头结点的左指针指向新节点。 - `return left_head`:返回双向链表的头结点。 - `return convert(self.root)`:调用递归函数convert并返回结果。 - `def inorder_traversal(self, root):`:定义一个中序遍历BST的函数。 - `if not root:`:如果该节点为空,则返回。 - `self.inorder_traversal(root.left)`:递归遍历左子树。 - `print(root.val, end=' ')`:输出当前节点的值。 - `self.inorder_traversal(root.right)`:递归遍历右子树。 - `def print_bst(self):`:定义一个打印BST的函数。 - `self.inorder_traversal(self.root)`:调用中序遍历函数遍历BST。 - `print()`:输出一个空行。 - `def traverse_doubly_linked_list(self, head):`:定义一个遍历双向链表的函数。 - `cur_node = head`:将当前节点指向链表的头结点。 - `while cur_node:`:遍历整个链表,直到当前节点为空。 - `print(cur_node.val, end=' ')`:输出当前节点的值。 - `cur_node = cur_node.next`:将当前节点指向下一个节点。 - `print()`:输出一个空行。 - `def reverse_traverse_doubly_linked_list(self, head):`:定义一个逆序遍历双向链表的函数。 - `cur_node = head`:将当前节点指向链表的头结点。 - `while cur_node.next:`:找到链表的尾结点。 - `cur_node = cur_node.next`:将当前节点指向下一个节点。 - `while cur_node:`:逆序遍历整个链表,直到当前节点为空。 - `print(cur_node.val, end=' ')`:输出当前节点的值。 - `cur_node = cur_node.prev`:将当前节点指向上一个节点。 - `print()`:输出一个空行。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值