6.2-数据结构&算法-队列二叉树

一、队列
1.基本特征:先进先出,FIFO
2.基本操作:压入(push)、弹出(pop)
3.实现要点:初始化空间,从前端(front)弹出,从后端(rear)压入,循环使用,判空判满
思考:用堆栈实现队列。二、链表
1.基本特征:内存中不连续的节点序列,彼此之间通过指针相互关联,前指针(prev)指向前节点,后指针(next)指向后节点。
2.基本操作:追加、插入、删除、遍历
3.实现要点:
void 讲故事 (void) {
  从前有座山;
  山里有个庙;
  庙里有个老和尚;
  if (老和尚圆寂了)
    return;
  讲故事 ();
}
三、二叉树
1.基本特征
1)树型结构的最简模型,每个节点最多有两个子节点。
2)单根。除根节点外每个节点有且仅有一个父节点,整棵树只有一个根节点。
3)递归结构,用递归处理二叉树问题可以简化算法。
2.基本操作
1)生成
2)遍历
D-L-R:前序遍历
L-D-R:中序遍历
L-R-D:后序遍历
有序二叉树(二叉搜索树)
L<=D<=R
50 70 20 60 40 30 10 90 80
               50
              /  
           /--    --
        20|          70
        /          /  
      10    40    60    90
           /           /
         30          80
        /
      10
中序遍历:10 20 30 40 50 60 70 80 90
bstree.cpp
#include <iostream>
using namespace std;
// 有序二叉树(二叉搜索树)
class Tree {
public:
    // 构造过程中初始化为空树
    Tree (void) : m_root (NULL), m_size (0) {}
    // 析构过程中销毁剩余节点
    ~Tree (void) {
        clear ();
    }
    // 插入数据
    void insert (int data) {
        insert (new Node (data), m_root);
        ++m_size;
    }
    // 删除第一个匹配数据,不存在返回false
    bool erase  (int data) {
        Node*& node = find (data, m_root);
        if (node) {
            // 左插右
            insert (node->m_left, node->m_right);
            Node* temp = node;
            // 右提升
            node = node->m_right;
            delete temp;
            --m_size;
            return true;
        }
        return false;
    }
    // 删除所有匹配数据
    void remove (int data) {
        while (erase (data));
    }
    // 清空树
    void clear (void) {
        clear (m_root);
        m_size = 0;
    }
    // 将所有的_old替换为_new
    void update (int _old, int _new) {
        while (erase (_old))
            insert (_new);
    }
    // 判断data是否存在
    bool find (int data) {
        return find (data, m_root) != NULL;
    }
    // 中序遍历
    void travel (void) {
        travel (m_root);
        cout << endl;
    }
    // 获取大小
    size_t size (void) {
        return m_size;
    }
    // 获取树高
    size_t height (void) {
        return height (m_root);
    }
private:
    // 节点
    class Node {
    public:
        Node (int data) : m_data (data),
            m_left (NULL), m_right (NULL) {}
        int m_data; // 数据
        Node* m_left; // 左树
        Node* m_right; // 右树
    };
    void insert (Node* node, Node*& tree) {
        if (! tree)
            tree = node;
        else if (node) {
            if (node->m_data < tree->m_data)
                insert (node, tree->m_left);
            else
                insert (node, tree->m_right);
        }
    }
    // 返回子树tree中值与data相匹配的节点的父节点中
    // 指向该节点的成员变量的别名
    Node*& find (int data, Node*& tree) {
        if (! tree)
            return tree;
        else
        if (data == tree->m_data)
            return tree;
        else
        if (data < tree->m_data)
            return find (data, tree->m_left);
        else
            return find (data, tree->m_right);
    }
    void clear (Node*& tree) {
        if (tree) {
            clear (tree->m_left);
            clear (tree->m_right);
            delete tree;
            tree = NULL;
        }
    }
    void travel (Node* tree) {
        if (tree) {
            travel (tree->m_left);
            cout << tree->m_data << ' ';
            travel (tree->m_right);
        }
    }
    size_t height (Node* tree) {
        if (tree) {
            size_t lh = height (tree->m_left);
            size_t rh = height (tree->m_right);
            return (lh > rh ? lh : rh) + 1;
        }
        return 0;
    }
    Node* m_root; // 树根
    size_t m_size; // 大小
};
int main (void) {
    Tree tree;
    tree.insert (50);
    tree.insert (70);
    tree.insert (20);
    tree.insert (60);
    tree.insert (40);
    tree.insert (30);
    tree.insert (10);
    tree.insert (90);
    tree.insert (80);
    tree.travel ();
    cout << tree.size () << ' ' << tree.height ()
        << endl;
    tree.erase (70);
    tree.travel ();
    tree.insert (70);
    tree.insert (70);
    tree.insert (70);
    tree.travel ();
    tree.remove (70);
    tree.travel ();
    tree.insert (40);
    tree.insert (40);
    tree.travel ();
    tree.update (40, 69);
    tree.travel ();
    cout << boolalpha << tree.find (50) << endl;
    cout << tree.find (55) << endl;
    tree.clear ();
    tree.travel ();
    return 0;
}

list.cpp

#include <iostream>
#include <stdexcept>
using namespace std;
// 双向线性链表
class List {
public:
    // 构造过程中初始化为空链表
    List (void) : m_head (NULL), m_tail (NULL) {}
    // 析构过程中销毁剩余的节点
    ~List (void) {
        for (Node* next; m_head; m_head = next) {
            next = m_head->m_next;
            delete m_head;
        }
    }
    // 追加
    void append (int data) {
        m_tail = new Node (data, m_tail);
        if (m_tail->m_prev)
            m_tail->m_prev->m_next = m_tail;
        else
            m_head = m_tail;
    }
    // 插入
    void insert (size_t pos, int data) {
        for (Node* find = m_head; find;
            find = find->m_next)
            if (pos-- == 0) {
                Node* node = new Node (data,
                    find->m_prev, find);
                if (node->m_prev)
                    node->m_prev->m_next = node;
                else
                    m_head = node;
                node->m_next->m_prev = node;
                return;
            }
        throw out_of_range ("链表越界!");
    }
    // 删除
    void erase (size_t pos) {
        for (Node* find = m_head; find;
            find = find->m_next)
            if (pos-- == 0) {
                if (find->m_prev)
                    find->m_prev->m_next =
                        find->m_next;
                else
                    m_head = find->m_next;
                if (find->m_next)
                    find->m_next->m_prev =
                        find->m_prev;
                else
                    m_tail = f


                return;
            }
        throw out_of_range ("链表越界!");
    }
    // 正向遍历
    void forward (void) const {
        for (Node* node = m_head; node;
            node = node->m_next)
            cout << node->m_data << ' ';
        cout << endl;
    }
    // 反向遍历
    void backward (void) const {
        for (Node* node = m_tail; node;
            node = node->m_prev)
            cout << node->m_data << ' ';
        cout << endl;
    }
    // 下标访问
    int& operator[] (size_t index) {
        for (Node* find = m_head; find;
            find = find->m_next)
            if (index-- == 0)
                return find->m_data;
        throw out_of_range ("链表越界!");
    }
    const int& operator[] (size_t index) const {
        return const_cast<List&> (*this) [index];
    }
private:
    // 节点
    class Node {
    public:
        Node (int data = 0, Node* prev = NULL,
            Node* next = NULL) : m_data (data),
            m_prev (prev), m_next (next) {}
        int m_data; // 数据
        Node* m_prev; // 前指针
        Node* m_next; // 后指针
    };
    Node* m_head; // 头指针
    Node* m_tail; // 尾指针
};
int main (void) {
    try {
        List list;
        list.append (10);
        list.append (30);
        list.append (50);
        list.append (60);
        list.append (80);
        list.insert (1, 20);
        list.insert (3, 40);
        list.insert (6, 70);
        list.forward ();
        list.backward ();
        list.erase (5);
        list.erase (5);
        list.erase (5);
        list.forward ();
        for (size_t i = 0; i < 5; ++i)
            ++list[i];
        const List& cr = list;
        for (size_t i = 0; i < 5; ++i)
            cout << /*++*/cr[i] << ' ';
        cout << endl;
    }
    catch (exception& ex) {
        cout << ex.what () << endl;
        return -1;
    }
    return 0;
}

listex.cpp

// 练习:实现一个单向线性链表类
// 1.建立、测长、正反向打印
// 2.逆转
// 3.获取中间节点值,单次遍历
// 4.有序链表的插入和删除
#include <iostream>
#include <stdexcept>
using namespace std;
class List {
public:
    List (void) : m_head (NULL), m_tail (NULL) {}
    ~List (void) {
        for (Node* next; m_head; m_head = next) {
            next = m_head->m_next;
            delete m_head;
        }
    }
    void append (int data) {
        Node* node = new Node (data);
        if (m_tail)
            m_tail->m_next = node;
        else
            m_head = node;
        m_tail = node;
    }
    size_t size (void) const {
        size_t cn = 0;
        for (Node* node = m_head; node;
            node = node->m_next)
            ++cn;
        return cn;
    }
    void print (void) const {
        for (Node* node = m_head; node;
            node = node->m_next)
            cout << node->m_data << ' ';
        cout << endl;
    }
    void rprint (void) const {
        rprint (m_head);
        cout << endl;
    }
    /*
    void reverse (void) {
        reverse (m_head);
        swap (m_head, m_tail);
    }
    */
    void reverse (void) {
        if (m_head != m_tail) {
            Node* p1 = m_tail = m_head;
            Node* p2 = p1->m_next;
            Node* p3 = p2->m_next;
            for (p1->m_next=NULL;p3;p3=p3->m_next) {
                p2->m_next = p1;
                p1 = p2;
                p2 = p3;
            }
            (m_head = p2)->m_next = p1;
        }
    }
    int middle (void) const {
        if (! m_head || ! m_tail)
            throw underflow_error ("链表下溢!");
        if (m_head == m_tail)
            return m_head->m_data;
        Node* mid = m_head;
        for (Node* node = m_head;
            node->m_next && node->m_next->m_next;
            node = node->m_next->m_next)
            mid = mid->m_next;
        return mid->m_data;
    }
    // 插入data,仍然保持有序
    void insert (int data) {
    }
    // 删除所有的data
    void remove (int data) {
    }
private:
    class Node {
    public:
        Node (int data = 0, Node* next = NULL) :
            m_data (data), m_next (next) {}
        int m_data;
        Node* m_next;
    };
    void rprint (Node* head) const {
        if (head) {
            rprint (head->m_next);
            cout << head->m_data << ' ';
        }
    }
    void reverse (Node* head) {
        if (head && head->m_next) {
            reverse (head->m_next);
            head->m_next->m_next = head;
            head->m_next = NULL;
        }
    }
    Node* m_head;
    Node* m_tail;
};
int main (void) {
    List list;
    for (int i = 0; i < 11; ++i)
        list.append (i);
    cout << list.size () << endl;
    list.print ();
    list.rprint ();
    list.reverse ();
    list.print ();
    cout << list.middle () << endl;
    return 0;
}

lqueue.cpp

#include <iostream>
using namespace std;
// 基于链式表的队列
class Queue {
public:
    // 在构造过程中初始化为空队列
    Queue (void) : m_rear (NULL), m_front (NULL) {}
    // 在析构过程中销毁剩余的节点
    ~Queue (void) {
        for (Node* next; m_front; m_front = next) {
            next = m_front->m_next;
            delete m_front;
        }
    }
    // 压入
    void push (int data) {
        Node* node = new Node (data);
        if (m_rear)
            m_rear->m_next = node;
        else
            m_front = node;
        m_rear = node;
    }
    // 弹出
    int pop (void) {
        if (empty ())
            throw UnderFlow ();
        int data = m_front->m_data;
        Node* next = m_front->m_next;
        delete m_front;
        if (! (m_front = next))
            m_rear = NULL;
        return data;
    }
    // 判空
    bool empty (void) const {
        return ! m_front && ! m_rear;
    }
private:
    // 下溢异常
    class UnderFlow : public exception {
        const char* what (void) const throw () {
            return "队列下溢!";
        }
    };
    // 节点
    class Node {
    public:
        Node (int data = 0, Node* next = NULL) :
            m_data (data), m_next (next) {}
        int m_data; // 数据
        Node* m_next; // 后指针
    };
    Node* m_rear; // 后端
    Node* m_front; // 前端
};
int main (void) {
    try {
        Queue queue;
        for (int i = 0; i < 10; ++i)
            queue.push (i);
        while (! queue.empty ())
            cout << queue.pop () << endl;
    }Node* 
    catch (exception& ex) {
        cout << ex.what () << endl;
        return -1;
    }
    return 0;
    de* 
}

lstack.h

#ifndef _LSTACK_H
#define _LSTACK_H
#include <stdexcept>
using namespace std;
// 基于链式表的堆栈
class Stack {
public:
    // 构造过程中初始化为空堆栈
    Stack (void) : m_top (NULL) {}
    // 析构过程中销毁剩余的节点
    ~Stack (void) {
        for (Node* next; m_top; m_top = next) {
            next = m_top->m_next;
            delete m_top;
        }
    }
    // 压入
    void push (int data) {
        /*
        Node* node = new Node;
        node->m_data = data;
        node->m_next = m_top;
        m_top = node;*/
        m_top = new Node (data, m_top);
    }
    // 弹出
    int pop (void) {
        if (empty ())
            throw UnderFlow ();
        int data = m_top->m_data;
        Node* next = m_top->m_next;
        delete m_top;
        m_top = next;
        return data;
    }
    // 判空
    bool empty (void) const {
        return ! m_top;
    }
private:
    // 下溢异常
    class UnderFlow : public exception {
        const char* what (void) const throw () {
            return "堆栈下溢!";
        }
    };
    // 节点
    class Node {
    public:
        Node (int data = 0, Node* next = NULL) :
            m_data (data), m_next (next) {}
        int m_data; // 数据
        Node* m_next; // 后指针
    };
    Node* m_top; // 栈顶
};
#endif // _LSTACK_H

queue.cpp

#include <iostream>
using namespace std;
// 基于顺序表的队列
class Queue {
public:
    // 构造过程中分配内存
    Queue (size_t size = 5) :
        m_array (new int[size]), m_size (size),
        m_rear (0), m_front (0), m_count (0) {}
    // 析构过程中释放内存
    ~Queue (void) {
        if (m_array) {
            delete[] m_array;
            m_array = NULL;
        }
    }
    // 压入
    void push (int data) {
        if (full ())
            throw OverFlow ();
        if (m_rear >= m_size)
            m_rear = 0;
        ++m_count;
        m_array[m_rear++] = data;
    }
    // 弹出
    int pop (void) {
        if (empty ())
            throw UnderFlow ();
        if (m_front >= m_size)
            m_front = 0;
        --m_count;
        return m_array[m_front++];
    }
    // 判空
    bool empty (void) const {
        return ! m_count;
    }
    // 判满
    bool full (void) const {
        return m_count == m_size;
    }
private:
    // 上溢异常
    class OverFlow : public exception {
        const char* what (void) const throw () {
            return "队列上溢!";
        }
    };
    // 下溢异常
    class UnderFlow : public exception {
        const char* what (void) const throw () {
            return "队列下溢!";
        }
    };
    int* m_array; // 数组
    size_t m_size; // 容量
    size_t m_rear; // 后端
    size_t m_front; // 前端
    size_t m_count; // 计数
};
int main (void) {
    try {
        Queue queue;
        queue.push (10);
        queue.push (20);
        queue.push (30);
        queue.push (40);
        queue.push (50);
//        queue.push (60);
        cout << queue.pop () << endl; // 10
        queue.push (60);
        cout << queue.pop () << endl; // 20
        queue.push (70);
//        queue.push (80);
        cout << queue.pop () << endl; // 30
        cout << queue.pop () << endl; // 40
        cout << queue.pop () << endl; // 50
        cout << queue.pop () << endl; // 60
        cout << queue.pop () << endl; // 70
//        queue.pop ();
    }
    catch (exception& ex) {
        cout << ex.what () << endl;
        return -1;
    }
    return 0;
}

squeue.cpp

#include <iostream>
#include "lstack.h"
using namespace std;
// 基于堆栈的队列
class Queue {
public:
    // 压入
    void push (int data) {
        m_i.push (data);
    }
    // 弹出
    int pop (void) {
        if (m_o.empty ()) {
            if (m_i.empty ())
                throw underflow_error("队列下溢!");
            while (! m_i.empty ())
                m_o.push (m_i.pop ());
        }
        return m_o.pop ();
    }
    // 判空
    bool empty (void) const {
        return m_i.empty () && m_o.empty ();
    }
private:
    Stack m_i; // 输入栈
    Stack m_o; // 输出栈
};
int main (void) {
    try {
        Queue queue;
        for (int i = 0; i < 10; ++i)
            queue.push (i);
        cout << queue.pop () << endl; // 0
        cout << queue.pop () << endl; // 1
        cout << queue.pop () << endl; // 2
        cout << queue.pop () << endl; // 3
        cout << queue.pop () << endl; // 4
        queue.push (10);
        queue.push (11);
        queue.push (12);
        while (! queue.empty ())
            cout << queue.pop () << endl;
    }
    catch (exception& ex) {
        cout << ex.what () << endl;
        return -1;
    }
    return 0;
}
原文地址:https://www.cnblogs.com/xuxaut-558/p/10028319.html