数据结构的通用模板(C++)

1. 链表

链表头文件 (LinkedList.h)

#ifndef LINKEDLIST_H
#define LINKEDLIST_H

class LinkedList {
    struct Node {
        int val;
        Node* next;
        Node(int x) : val(x), next(nullptr) {}
    };

    Node* head;

public:
    LinkedList();
    ~LinkedList();
    void add(int val);
    void remove(int val);
    void print();
    // 可以添加更多的函数声明
};

#endif

链表实现 (LinkedList.cpp)

#include "LinkedList.h"
#include <iostream>

LinkedList::LinkedList() : head(nullptr) {}

LinkedList::~LinkedList() {
    Node* current = head;
    while (current != nullptr) {
        Node* next = current->next;
        delete current;
        current = next;
    }
    head = nullptr;
}

void LinkedList::add(int val) {
    Node* newNode = new Node(val);
    newNode->next = head;
    head = newNode;
}

void LinkedList::remove(int val) {
    Node* current = head;
    Node* prev = nullptr;

    while (current != nullptr && current->val != val) {
        prev = current;
        current = current->next;
    }

    if (current == nullptr) return; // 找不到元素

    if (prev == nullptr) {
        head = current->next; // 移除头部元素
    } else {
        prev->next = current->next; // 移除头部以外的元素
    }

    delete current;
}

void LinkedList::print() {
    Node* temp = head;
    while (temp != nullptr) {
        std::cout << temp->val << " -> ";
        temp = temp->next;
    }
    std::cout << "NULL" << std::endl;
}

链表测试 (main.cpp)

#include "LinkedList.h"

int main() {
    LinkedList list;
    list.add(1);
    list.add(2);
    list.add(3);
    list.print();
    // 添加更多测试用例
    return 0;
}

2. 双向链表

双向链表头文件 (DoublyLinkedList.h)

#ifndef DOUBLYLINKEDLIST_H
#define DOUBLYLINKEDLIST_H

class DoublyLinkedList {
    struct Node {
        int val;
        Node* prev;
        Node* next;
        Node(int x) : val(x), prev(nullptr), next(nullptr) {}
    };

    Node* head;
    Node* tail;

public:
    DoublyLinkedList();
    ~DoublyLinkedList();
    void addFront(int val);
    void addBack(int val);
    void remove(int val);
    void printForward();
    void printBackward();
};

#endif

双向链表实现 (DoublyLinkedList.cpp)

#include "DoublyLinkedList.h"
#include <iostream>

DoublyLinkedList::DoublyLinkedList() : head(nullptr), tail(nullptr) {}

DoublyLinkedList::~DoublyLinkedList() {
    Node* current = head;
    while (current != nullptr) {
        Node* next = current->next;
        delete current;
        current = next;
    }
}

void DoublyLinkedList::addFront(int val) {
    Node* newNode = new Node(val);
    newNode->next = head;
    if (head != nullptr) {
        head->prev = newNode;
    } else {
        tail = newNode;
    }
    head = newNode;
}

void DoublyLinkedList::addBack(int val) {
    Node* newNode = new Node(val);
    newNode->prev = tail;
    if (tail != nullptr) {
        tail->next = newNode;
    } else {
        head = newNode;
    }
    tail = newNode;
}

void DoublyLinkedList::remove(int val) {
    Node* current = head;
    while (current != nullptr && current->val != val) {
        current = current->next;
    }
    if (current == nullptr) return; // 找不到元素

    if (current->prev != nullptr) {
        current->prev->next = current->next;
    } else {
        head = current->next; // 移除头部元素
    }

    if (current->next != nullptr) {
        current->next->prev = current->prev;
    } else {
        tail = current->prev; // 移除头部以外的元素
    }

    delete current;
}

void DoublyLinkedList::printForward() {
    Node* temp = head;
    while (temp != nullptr) {
        std::cout << temp->val << " -> ";
        temp = temp->next;
    }
    std::cout << "NULL" << std::endl;
}

void DoublyLinkedList::printBackward() {
    Node* temp = tail;
    while (temp != nullptr) {
        std::cout << temp->val << " -> ";
        temp = temp->prev;
    }
    std::cout << "NULL" << std::endl;
}

双向链表测试 (main.cpp)

#include "DoublyLinkedList.h"

int main() {
    DoublyLinkedList list;
    list.addFront(1);
    list.addFront(2);
    list.addBack(3);
    list.addBack(4);
    list.printForward();
    list.printBackward();
    list.remove(2);
    list.printForward();
    return 0;
}

3. 动态数组(使用 std::vector

动态数组在 C++ 中是通过 std::vector 实现的,因此不需要单独的头文件和实现文件。可以直接在测试文件中使用它。

测试 (main.cpp)

#include <iostream>
#include <vector>

int main() {
    std::vector<int> vec;
    vec.push_back(1);
    vec.push_back(2);
    vec.push_back(3);

    // 打印测试
    for (int num : vec) {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    return 0;
}

4. 栈

栈头文件 (Stack.h)

#ifndef STACK_H
#define STACK_H

#include <list>

class Stack {
    std::list<int> container;

public:
    void push(int val);
    void pop();
    int top();
    bool isEmpty();
};

#endif

栈实现 (Stack.cpp)

#include "Stack.h"

void Stack::push(int val) {
    container.push_back(val);
}

void Stack::pop() {
    if (!container.empty()) {
        container.pop_back();
    }
}

int Stack::top() {
    return container.back();
}

bool Stack::isEmpty() {
    return container.empty();
}

栈测试 (main.cpp)

#include "Stack.h"
#include <iostream>

int main() {
    Stack stack;
    stack.push(1);
    stack.push(2);
    stack.push(3);
    while (!stack.isEmpty()) {
        std::cout << stack.top() << std::endl;
        stack.pop();
    }
    return 0;
}

5. 队列

队列头文件 (Queue.h)

#ifndef QUEUE_H
#define QUEUE_H

#include <list>

class Queue {
    std::list<int> container;

public:
    void enqueue(int val);
    void dequeue();
    int front();
    bool isEmpty();
};

#endif

队列实现 (Queue.cpp)

#include "Queue.h"

void Queue::enqueue(int val) {
    container.push_back(val);
}

void Queue::dequeue() {
    if (!container.empty()) {
        container.pop_front();
    }
}

int Queue::front() {
    return container.front();
}

bool Queue::isEmpty() {
    return container.empty();
}

队列测试 (main.cpp)

#include "Queue.h"
#include <iostream>

int main() {
    Queue queue;
    queue.enqueue(1);
    queue.enqueue(2);
    queue.enqueue(3);
    while (!queue.isEmpty()) {
        std::cout << queue.front() << std::endl;
        queue.dequeue();
    }
    return 0;
}

6. 二叉树

二叉树头文件 (BinaryTree.h)

#ifndef BINARYTREE_H
#define BINARYTREE_H

#include <iostream>

class BinaryTree {
    struct TreeNode {
        int val;
        TreeNode *left, *right;
        TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
    };

    TreeNode* root;

    void inorder(TreeNode* node);
    void insert(TreeNode** node, int val);
    void destroyTree(TreeNode* node);

public:
    BinaryTree();
    ~BinaryTree();
    void insert(int val);
    void inorderTraversal();
};

#endif

二叉树实现 (BinaryTree.cpp)

#include "BinaryTree.h"

BinaryTree::BinaryTree() : root(nullptr) {}

BinaryTree::~BinaryTree() {
    destroyTree(root);
}

void BinaryTree::destroyTree(TreeNode* node) {
    if (node != nullptr) {
        destroyTree(node->left);
        destroyTree(node->right);
        delete node;
    }
}

void BinaryTree::insert(int val) {
    insert(&root, val);
}

void BinaryTree::insert(TreeNode** node, int val) {
    if (*node == nullptr) {
        *node = new TreeNode(val);
    } else if (val < (*node)->val) {
        insert(&((*node)->left), val);
    } else {
        insert(&((*node)->right), val);
    }
}

void BinaryTree::inorderTraversal() {
    inorder(root);
}

void BinaryTree::inorder(TreeNode* node) {
    if (node != nullptr) {
        inorder(node->left);
        std::cout << node->val << " ";
        inorder(node->right);
    }
}

二叉树测试 (main.cpp)

#include "BinaryTree.h"

int main() {
    BinaryTree tree;
    tree.insert(5);
    tree.insert(3);
    tree.insert(7);
    tree.insert(1);
    tree.inorderTraversal();
    return 0;
}

7. 二叉搜索树

由于二叉搜索树(BST)的实现与普通二叉树非常相似,可以重用大部分 BinaryTree 的代码,并在插入和查找方法中加入适当的逻辑来保证二叉搜索树的性质。

二叉搜索树头文件 (BST.h)

#ifndef BST_H
#define BST_H

class BST {
    struct TreeNode {
        int val;
        TreeNode *left, *right;
        TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
    };

    TreeNode* root;

    void inorder(TreeNode* node);
    void insert(TreeNode** node, int val);
    TreeNode* search(TreeNode* node, int val);
    void destroyTree(TreeNode* node);

public:
    BST();
    ~BST();
    void insert(int val);
    bool search(int val);
    void inorderTraversal();
};

#endif

二叉搜索树实现 (BST.cpp)

#include "BST.h"
#include <iostream>

BST::BST() : root(nullptr) {}

BST::~BST() {
    destroyTree(root);
}

void BST::destroyTree(TreeNode* node) {
    if (node != nullptr) {
        destroyTree(node->left);
        destroyTree(node->right);
        delete node;
    }
}

void BST::insert(int val) {
    insert(&root, val);
}

void BST::insert(TreeNode** node, int val) {
    if (*node == nullptr) {
        *node = new TreeNode(val);
    } else if (val < (*node)->val) {
        insert(&((*node)->left), val);
    } else {
        insert(&((*node)->right), val);
    }
}

bool BST::search(int val) {
    return search(root, val) != nullptr;
}

BST::TreeNode* BST::search(TreeNode* node, int val) {
    if (node == nullptr || node->val == val) {
        return node;
    }
    if (val < node->val) {
        return search(node->left, val);
    } else {
        return search(node->right, val);
    }
}

void BST::inorderTraversal() {
    inorder(root);
}

void BST::inorder(TreeNode* node) {
    if (node != nullptr) {
        inorder(node->left);
        std::cout << node->val << " ";
        inorder(node->right);
    }
}

二叉搜索树测试 (main.cpp)

#include "BST.h"

int main() {
    BST tree;
    tree.insert(5);
    tree.insert(3);
    tree.insert(7);
    tree.insert(1);
    tree.inorderTraversal();
    std::cout << std::endl;
    std::cout << "Search 3: " << (tree.search(3) ? "Found" : "Not Found") << std::endl;
    std::cout << "Search 4: " << (tree.search(4) ? "Found" : "Not Found") << std::endl;
    return 0;
}

8. 哈希表

哈希表头文件 (HashTable.h)

#ifndef HASHTABLE_H
#define HASHTABLE_H

#include <vector>
#include <list>
#include <utility>

class HashTable {
std::vector<std::list<std::pair<int, int>>> table;
int hashFunction(int key);

public:
HashTable(int size);
void insert(int key, int value);
bool search(int key, int& value);
void remove(int key);
};

#endif

哈希表实现 (HashTable.cpp)

#include "HashTable.h"

HashTable::HashTable(int size) : table(size) {}

int HashTable::hashFunction(int key) {
    return key % table.size();
}

void HashTable::insert(int key, int value) {
    int hashValue = hashFunction(key);
    for (auto& kv : table[hashValue]) {
        if (kv.first == key) {
            kv.second = value;
            return;
        }
    }
    table[hashValue].emplace_back(key, value);
}

bool HashTable::search(int key, int& value) {
    int hashValue = hashFunction(key);
    for (auto& kv : table[hashValue]) {
        if (kv.first == key) {
            value = kv.second;
            return true;
        }
    }
    return false;
}

void HashTable::remove(int key) {
    int hashValue = hashFunction(key);
    table[hashValue].remove_if([key](std::pair<int, int> kv) { return kv.first == key; });
}

哈希表测试 (main.cpp)

#include "HashTable.h"
#include <iostream>

int main() {
    HashTable ht(10);
    ht.insert(1, 100);
    ht.insert(2, 200);
    ht.insert(11, 300);

    int value;
    if (ht.search(1, value)) {
        std::cout << "Key 1 has value " << value << std::endl;
    } else {
        std::cout << "Key 1 not found" << std::endl;
    }

    ht.remove(1);
    if (ht.search(1, value)) {
        std::cout << "Key 1 has value " << value << std::endl;
    } else {
        std::cout << "Key 1 not found" << std::endl;
    }

    return 0;
}

9. 图

图头文件 (Graph.h)

#ifndef GRAPH_H
#define GRAPH_H

#include <list>
#include <vector>

class Graph {
    int V; 
    std::vector<std::list<int>> adj; 

public:
    Graph(int V);
    void addEdge(int v, int w);
    void BFS(int s);
    // 其他方法,如 DFS 等
};

#endif

图实现 (Graph.cpp)

#include "Graph.h"
#include <queue>
#include <iostream>

Graph::Graph(int V) : V(V), adj(V) {}

void Graph::addEdge(int v, int w) {
    adj[v].push_back(w); // 如果是无向图,需要添加 adj[w].push_back(v);
}

void Graph::BFS(int s) {
    std::vector<bool> visited(V, false);
    std::queue<int> queue;

    visited[s] = true;
    queue.push(s);

    while (!queue.empty()) {
        s = queue.front();
        std::cout << s << " ";
        queue.pop();

        for (auto adjecent : adj[s]) {
            if (!visited[adjecent]) {
                visited[adjecent] = true;
                queue.push(adjecent);
            }
        }
    }
}

图测试 (main.cpp)

#include "Graph.h"

int main() {
    Graph g(4);
    g.addEdge(0, 1);
    g.addEdge(0, 2);
    g.addEdge(1, 2);
    g.addEdge(2, 0);
    g.addEdge(2, 3);
    g.addEdge(3, 3);

    g.BFS(2); // 从顶点 2 开始进行广度优先搜索
    return 0;
}

10. 堆

堆头文件 (Heap.h)

#ifndef HEAP_H
#define HEAP_H

#include <vector>

class Heap {
    std::vector<int> heap;

    void heapifyUp(int index);
    void heapifyDown(int index);

public:
    void insert(int key);
    int extractMax();
    int size() const;
    bool isEmpty() const;
};

#endif

堆实现 (Heap.cpp)

#include "Heap.h"
#include <stdexcept>

void Heap::insert(int key) {
    heap.push_back(key);
    heapifyUp(heap.size() - 1);
}

int Heap::extractMax() {
    if (isEmpty()) throw std::out_of_range("Heap is empty");
    int root = heap[0];
    heap[0] = heap.back();
    heap.pop_back();
    heapifyDown(0);
    return root;
}

int Heap::size() const {
    return heap.size();
}

bool Heap::isEmpty() const {
    return heap.empty();
}

void Heap::heapifyUp(int index) {
    while (index != 0 && heap[(index - 1) / 2] < heap[index]) {
        std::swap(heap[(index - 1) / 2], heap[index]);
        index = (index - 1) / 2;
    }
}

void Heap::heapifyDown(int index) {
    int largest = index;
    int left = 2 * index + 1;
    int right = 2 * index + 2;

    if (left < heap.size() && heap[left] > heap[largest]) {
        largest = left;
    }
    if (right < heap.size() && heap[right] > heap[largest]) {
        largest = right;
    }
    if (largest != index) {
        std::swap(heap[index], heap[largest]);
        heapifyDown(largest);
    }
}

堆测试 (main.cpp)

#include "Heap.h"
#include <iostream>

int main() {
    Heap maxHeap;
    maxHeap.insert(3);
    maxHeap.insert(2);
    maxHeap.insert(15);

    std::cout << "Maximum value: " << maxHeap.extractMax() << std::endl;

    return 0;
}

11. 堆(最小堆)

最小堆头文件 (MinHeap.h)

#ifndef MINHEAP_H
#define MINHEAP_H

#include <vector>

class MinHeap {
    std::vector<int> heap;

    void heapifyUp(int index);
    void heapifyDown(int index);

public:
    MinHeap();
    void insert(int key);
    int extractMin();
    int size() const;
    bool isEmpty() const;
};

#endif

最小堆实现 (MinHeap.cpp)

#include "MinHeap.h"
#include <stdexcept>

MinHeap::MinHeap() {}

void MinHeap::insert(int key) {
    heap.push_back(key);
    heapifyUp(heap.size() - 1);
}

int MinHeap::extractMin() {
    if (isEmpty()) throw std::out_of_range("Heap is empty");
    int root = heap[0];
    heap[0] = heap.back();
    heap.pop_back();
    heapifyDown(0);
    return root;
}

int MinHeap::size() const {
    return heap.size();
}

bool MinHeap::isEmpty() const {
    return heap.empty();
}

void MinHeap::heapifyUp(int index) {
    while (index != 0 && heap[(index - 1) / 2] > heap[index]) {
        std::swap(heap[(index - 1) / 2], heap[index]);
        index = (index - 1) / 2;
    }
}

void MinHeap::heapifyDown(int index) {
    int smallest = index;
    int left = 2 * index + 1;
    int right = 2 * index + 2;

    if (left < heap.size() && heap[left] < heap[smallest]) {
        smallest = left;
    }
    if (right < heap.size() && heap[right] < heap[smallest]) {
        smallest = right;
    }
    if (smallest != index) {
        std::swap(heap[index], heap[smallest]);
        heapifyDown(smallest);
    }
}

最小堆测试 (main.cpp)

#include "MinHeap.h"
#include <iostream>

int main() {
    MinHeap minHeap;
    minHeap.insert(3);
    minHeap.insert(2);
    minHeap.insert(15);

    std::cout << "Minimum value: " << minHeap.extractMin() << std::endl;

    return 0;
}

12. 二分查找

二分查找头文件 (BinarySearch.h)

#ifndef BINARYSEARCH_H
#define BINARYSEARCH_H

#include <vector>

int binarySearch(const std::vector<int>& arr, int x);

#endif

二分查找实现 (BinarySearch.cpp)

#include "BinarySearch.h"

int binarySearch(const std::vector<int>& arr, int x) {
    int left = 0, right = arr.size() - 1;
    while (left <= right) {
        int mid = left + (right - left) / 2;
        if (arr[mid] == x) return mid;
        if (arr[mid] < x) left = mid + 1;
        else right = mid - 1;
    }
    return -1;
}

测试二分查找和快速排序 (main.cpp)

#include <iostream>
#include <vector>
#include "QuickSort.h" 
#include "BinarySearch.h" 

int main() {
    // 测试快速排序
    std::vector<int> arr = {10, 7, 8, 9, 1, 5};
    QuickSort::sort(arr, 0, arr.size() - 1);
    std::cout << "Sorted array: ";
    for (int num : arr) {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    // 测试二分查找
    int result = binarySearch(arr, 9); // 使用快速排序后的数组
    if (result != -1) std::cout << "Element found at index " << result << std::endl;
    else std::cout << "Element not found in the array" << std::endl;

    return 0;
}

13. 快速排序

快速排序头文件 (QuickSort.h)

#ifndef QUICKSORT_H
#define QUICKSORT_H

#include <vector>

class QuickSort {
public:
    static void sort(std::vector<int>& arr, int low, int high);
private:
    static int partition(std::vector<int>& arr, int low, int high);
};

#endif

快速排序实现 (QuickSort.cpp)

#include "QuickSort.h"

void QuickSort::sort(std::vector<int>& arr, int low, int high) {
    if (low < high) {
        int pi = partition(arr, low, high);
        sort(arr, low, pi - 1);
        sort(arr, pi + 1, high);
    }
}

int QuickSort::partition(std::vector<int>& arr, int low, int high) {
    int pivot = arr[high];
    int i = (low - 1);

    for (int j = low; j <= high - 1; j++) {
        if (arr[j] < pivot) {
            i++;
            std::swap(arr[i], arr[j]);
        }
    }
    std::swap(arr[i + 1], arr[high]);
    return (i + 1);
}

快速排序测试 (main.cpp)

#include "QuickSort.h"
#include <iostream>

int main() {
    std::vector<int> arr = {10, 7, 8, 9, 1, 5};
    QuickSort::sort(arr, 0, arr.size() - 1);
    // 打印排序后的数组
    for (int num : arr) {
        std::cout << num << " ";
    }
    std::cout << std::endl;
    return 0;
}

14. 归并排序

归并排序头文件 (MergeSort.h)

#ifndef MERGESORT_H
#define MERGESORT_H

#include <vector>

class MergeSort {
    public:
    static void sort(std::vector<int>& arr);
    private:
    static void mergeSort(std::vector<int>& arr, int left, int right);
    static void merge(std::vector<int>& arr, int left, int mid, int right);
};

#endif

归并排序实现 (MergeSort.cpp)

#include "MergeSort.h"

void MergeSort::sort(std::vector<int>& arr) {
    if (arr.size() > 1) {
        mergeSort(arr, 0, arr.size() - 1);
    }
}

void MergeSort::mergeSort(std::vector<int>& arr, int left, int right) {
    if (left < right) {
        int mid = left + (right - left) / 2;
        mergeSort(arr, left, mid);
        mergeSort(arr, mid + 1, right);
        merge(arr, left, mid, right);
    }
}

void MergeSort::merge(std::vector<int>& arr, int left, int mid, int right) {
    int n1 = mid - left + 1;
    int n2 = right - mid;

    std::vector<int> L(n1), R(n2);

    for (int i = 0; i < n1; i++)
        L[i] = arr[left + i];
    for (int j = 0; j < n2; j++)
        R[j] = arr[mid + 1 + j];

    int i = 0, j = 0, k = left;
    while (i < n1 && j < n2) {
        if (L[i] <= R[j]) {
            arr[k] = L[i];
            i++;
        } else {
            arr[k] = R[j];
            j++;
        }
        k++;
    }

    while (i < n1) {
        arr[k] = L[i];
        i++;
        k++;
    }

    while (j < n2) {
        arr[k] = R[j];
        j++;
        k++;
    }
}

归并排序测试 (main.cpp)

#include "MergeSort.h"
#include <iostream>

int main() {
    std::vector<int> arr = {12, 11, 13, 5, 6, 7};
    MergeSort::sort(arr);
    // 打印排序后的数组
    for (int num : arr) {
        std::cout << num << " ";
    }
    std::cout << std::endl;
    return 0;
}
面向对象程序设计课程作业 1. 请创建一个数据类型为T的链表类模板List,实现以下成员函数: 1) 默认构造函数List(),将该链表初始化为一个空链表(10分) 2) 拷贝构造函数List(const List& list),根据一个给定的链表构造当前链表(10分) 3) 析构函数~List(),释放链表中的所有节点(10分) 4) Push_back(T e)函数,往链表最末尾插入一个元素为e的节点(10分) 5) operator<<()友元函数,将链表的所有元素按顺序输出(10分) 6) operator=()函数,实现两个链表的赋值操作(10分) 7) operator+()函数,实现两个链表的连接,A=B+C(10分) 2. 请编写main函数,测试该类模板的正确性: 1) 用List模板定义一个List类型的模板类对象int_listB,从键盘读入m个整数,调用Push_back函数将这m个整数依次插入到该链表中;(4分) 2) 用List模板定义一个List类型的模板类对象int_listC,从键盘读入n个整数,调用Push_back函数将这n个整数依次插入到该链表中;(4分) 3) 用List模板定义一个List类型的模板类对象int_listA,调用List的成员函数实现A = B + C;(4分) 4) 用cout直接输出int_listA的所有元素(3分) 5) 用List模板定义List类型的模板类对象double_listA, double_listB, double_listC,重复上述操作。(15分) 3. 输入输出样例: 1) 输入样例 4 12 23 34 45 3 56 67 78 3 1.2 2.3 3.4 4 4.5 5.6 6.7 7.8 2) 输出样例 12 23 34 45 56 67 78 1.2 2.3 3.4 4.5 5.6 6.7 7.8
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值