zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    package相关知识
    【算法设计与分析】5个数7次比较排序的算法
    Android下的应用编程——用HTTP协议实现文件上传功能
    5个数通过7次比较排序的方法
    数据库范式(1NF、2NF、3NF、BCNF)
    HttpDownloader2011年09月20日 写好用于下载的类 并且封装好
    POJ 1692 DP
    POJ 1682 多重DP
    TYVJ 1744 逆序对数(加强版)
    POJ 2151 概率DP
  • 原文地址:https://www.cnblogs.com/xuxaut-558/p/10028319.html
Copyright © 2011-2022 走看看