首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >《C++程序设计》第9章-模板与群体数据

《C++程序设计》第9章-模板与群体数据

作者头像
啊阿狸不会拉杆
发布2026-01-21 13:31:34
发布2026-01-21 13:31:34
40
举报
        本文通过可运行代码示例详细讲解模板、线性群体数据结构(数组/链表/栈/队列)及排序查找算法,帮助读者深入理解C++泛型编程与数据组织技术。
9.1 函数模板与类模板

核心作用:实现泛型编程,使代码可处理任意数据类型

9.1.1 函数模板
代码语言:javascript
复制
#include <iostream>
using namespace std;

// 函数模板:交换任意类型的两个值
template <typename T>
void mySwap(T &a, T &b) {
    T temp = a;
    a = b;
    b = temp;
}

int main() {
    int x = 10, y = 20;
    mySwap(x, y);  // 自动推导为int类型
    cout << "x=" << x << ", y=" << y << endl;  // 输出:x=20, y=10

    string s1 = "Hello", s2 = "World";
    mySwap(s1, s2);  // 自动推导为string类型
    cout << "s1=" << s1 << ", s2=" << s2 << endl;  // 输出:s1=World, s2=Hello
    return 0;
}
代码语言:javascript
复制
9.1.2 类模板
代码语言:javascript
复制
#include <iostream>
using namespace std;

// 类模板:泛型栈实现
template <typename T, int MAX_SIZE=10>
class Stack {
private:
    T data[MAX_SIZE];
    int topIndex = -1;
public:
    void push(T val) {
        if (topIndex < MAX_SIZE-1) 
            data[++topIndex] = val;
        else
            cerr << "Stack overflow!" << endl;
    }
    
    T pop() {
        if (topIndex >= 0)
            return data[topIndex--];
        else {
            cerr << "Stack empty!" << endl;
            return T();  // 返回默认值
        }
    }
    
    bool isEmpty() const {
        return topIndex == -1;
    }
};

int main() {
    Stack<int> intStack;  // 存储int的栈
    intStack.push(100);
    intStack.push(200);
    cout << "Popped: " << intStack.pop() << endl;  // 200

    Stack<string> strStack;  // 存储string的栈
    strStack.push("C++");
    strStack.push("Templates");
    cout << "Popped: " << strStack.pop() << endl;  // Templates
    return 0;
}
代码语言:javascript
复制

9.2 线性群体

概念:元素按顺序排列,可通过索引或遍历访问

9.2.2 数组类模板
代码语言:javascript
复制
#include <iostream>
#include <stdexcept>
using namespace std;

template <typename T, size_t SIZE>
class Array {
private:
    T arr[SIZE];
public:
    T& operator[](size_t index) {
        if (index >= SIZE) 
            throw out_of_range("Index out of bounds!");
        return arr[index];
    }
    
    void fill(const T& value) {
        for (size_t i = 0; i < SIZE; ++i)
            arr[i] = value;
    }
    
    void print() const {
        for (size_t i = 0; i < SIZE; ++i)
            cout << arr[i] << " ";
        cout << endl;
    }
};

int main() {
    Array<double, 5> doubleArray;
    doubleArray.fill(3.14);
    doubleArray[2] = 99.9;  // 修改元素
    doubleArray.print();  // 输出:3.14 3.14 99.9 3.14 3.14
    return 0;
}
代码语言:javascript
复制
9.2.3 链表类
代码语言:javascript
复制
#include <iostream>
using namespace std;

template <typename T>
class LinkedList {
private:
    struct Node {
        T data;
        Node* next;
        Node(T val) : data(val), next(nullptr) {}
    };
    Node* head = nullptr;

public:
    void append(T val) {
        Node* newNode = new Node(val);
        if (!head) {
            head = newNode;
            return;
        }
        Node* current = head;
        while (current->next) 
            current = current->next;
        current->next = newNode;
    }
    
    void print() const {
        Node* current = head;
        while (current) {
            cout << current->data << " -> ";
            current = current->next;
        }
        cout << "NULL" << endl;
    }
    
    ~LinkedList() {
        Node* current = head;
        while (current) {
            Node* next = current->next;
            delete current;
            current = next;
        }
    }
};

int main() {
    LinkedList<string> list;
    list.append("Data");
    list.append("Structures");
    list.append("in C++");
    list.print();  // 输出:Data -> Structures -> in C++ -> NULL
    return 0;
}
链表结构示意图

9.3 群体数据的组织
9.3.1-3 排序算法实现
代码语言:javascript
复制
#include <iostream>
#include <vector>
using namespace std;

// 插入排序
template <typename T>
void insertionSort(vector<T>& arr) {
    for (int i = 1; i < arr.size(); ++i) {
        T key = arr[i];
        int j = i - 1;
        while (j >= 0 && arr[j] > key) {
            arr[j+1] = arr[j];
            j--;
        }
        arr[j+1] = key;
    }
}

// 测试排序
int main() {
    vector<int> nums = {12, 11, 13, 5, 6};
    insertionSort(nums);
    cout << "插入排序结果: ";
    for (int num : nums) cout << num << " ";  // 输出:5 6 11 12 13
    return 0;
}
代码语言:javascript
复制
9.3.4-5 查找算法
代码语言:javascript
复制
// 顺序查找
template <typename T>
int sequentialSearch(const vector<T>& arr, T target) {
    for (int i = 0; i < arr.size(); ++i)
        if (arr[i] == target) return i;
    return -1;
}

// 折半查找(要求有序数组)
template <typename T>
int binarySearch(const vector<T>& arr, T target) {
    int left = 0, right = arr.size() - 1;
    while (left <= right) {
        int mid = left + (right - left) / 2;
        if (arr[mid] == target) return mid;
        if (arr[mid] < target) left = mid + 1;
        else right = mid - 1;
    }
    return -1;
}
代码语言:javascript
复制

9.4 综合实例:银行账户管理系统改进
代码语言:javascript
复制
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

template <typename T>
class AccountManager {
private:
    vector<T> accounts;
public:
    void addAccount(const T& acc) {
        accounts.push_back(acc);
    }
    
    void displayAll() {
        for (auto& acc : accounts)
            acc.display();
    }
    
    void sortByBalance() {
        sort(accounts.begin(), accounts.end(), 
            [](const T& a, const T& b) {
                return a.getBalance() < b.getBalance();
            });
    }
};

class BankAccount {
private:
    string id;
    double balance;
public:
    BankAccount(string id, double bal) : id(id), balance(bal) {}
    void display() const {
        cout << "Account: " << id << ", Balance: $" << balance << endl;
    }
    double getBalance() const { return balance; }
};

int main() {
    AccountManager<BankAccount> manager;
    manager.addAccount(BankAccount("A1001", 5000));
    manager.addAccount(BankAccount("A1002", 1200));
    manager.addAccount(BankAccount("A1003", 8500));
    
    cout << "=== 排序前 ===" << endl;
    manager.displayAll();
    
    cout << "\n=== 按余额排序后 ===" << endl;
    manager.sortByBalance();
    manager.displayAll();
    return 0;
}

9.5 深度探索
9.5.1 模板实例化机制
  • 隐式实例化:编译器遇到模板使用时自动生成代码
  • 显式实例化:手动指定类型(template class Stack<int>;
9.5.2 可变参数模板
代码语言:javascript
复制
#include <iostream>
using namespace std;

// 基础递归终止函数
void printArgs() {
    cout << endl;
}

template <typename T, typename... Args>
void printArgs(T first, Args... args) {
    cout << first << " ";
    printArgs(args...);  // 递归调用
}

int main() {
    printArgs(1, 2.5, "Hello", 'A');  // 输出:1 2.5 Hello A 
    return 0;
}

知识体系总览

关键点总结
  1. 模板实现泛型:通过template<typename T>创建通用代码
  2. 线性群体特性
    • 数组:随机访问 O(1)
    • 链表:动态内存,插入/删除高效
  3. 排序算法选择
    • 小数据量:插入排序
    • 大数据量:快速排序(C++ std::sort)
  4. 工程实践建议
    • 优先使用STL(vector/list/stack)
    • 自定义数据结构需实现析构函数防止内存泄漏
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2026-01-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 9.1 函数模板与类模板
    • 9.1.1 函数模板
    • 9.1.2 类模板
  • 9.2 线性群体
    • 9.2.2 数组类模板
    • 9.2.3 链表类
  • 链表结构示意图
  • 9.3 群体数据的组织
    • 9.3.1-3 排序算法实现
    • 9.3.4-5 查找算法
  • 9.4 综合实例:银行账户管理系统改进
  • 9.5 深度探索
    • 9.5.1 模板实例化机制
    • 9.5.2 可变参数模板
  • 知识体系总览
  • 关键点总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档