数据结构-代码总结

news2025/6/3 7:15:54

下面代码自己上完课写着玩的,除了克鲁斯卡尔那里完全ai,其他基本上都是自己写的,具体请参考书本,同时也欢迎各位大佬来纠错

线性表

//线性表--顺序存储结构
#include<iostream>
using namespace std;
template<typename T>                //typename可以用class代替
struct sequentaillist {
        T* element;
        int size;                        //大小
        int capital;                //容量
};

template<typename T>
void initlist(sequentaillist<T>* List,int capital) {                                //初始化的过程其实就是分别初始化list三个变量
        List->element = new T[capital];                                //动态分配内存        
        List->size = 0;
        List->capital = capital;
}

template<typename T>
void destroylist(sequentaillist<T>* list) {                                        //销毁线性表
        delete[] list->element;                        //释放内存
}

template<typename T>
bool isempty(sequentaillist<T> list) {
        return list->size == 0;                        //判断是否为空表
}

template<typename T>
int getsize(sequentaillist<T> list) {                                        //返回表长
        return list.size;
}

template<typename T>
void clearlist(sequentaillist<T>* list) {                                //清空表长,就像未使用过一样
        if (list == nullptr) return;
        delete[] list->element;
        list->element = nullptr;
        list->size = 0;
        list->capital = 0;
}

template<typename T>
T getvalue(sequentaillist<T> list , int i) {                                        //获取表中第i个元素的值
        if (list.element == nullptr)        return nullptr;
        if (i<0 || i>list.size) {
                cout << "下标越界" << endl;
                return nullptr;
        }
        return list.element[i];
}

template<typename T>
int findelement(sequentaillist<T> list, int value) {                        //查找元素
        if (list.element == nullptr) return -1;
        for (int i = 0; i < list.size; i++) {
                if (list.element[i] == value) {
                        return i;
                }
        }
        return -1;                        //没找到
}

template<typename T>
void insert(sequentaillist<T>* list, int i , T value) {                                        //在第i个位置插入元素value
        if (list == nullptr) return;
        if (i<0 || i>list->size) {
                cout << "下标越界" << endl;
                return;
        }
        if (list->size == list->capital) {                                        //满了,扩容
                T* newelement = new T[list->capital * 2];                //扩容两倍
                for (int i = 0; i < list->size; i++) {
                        newelement[i] = list->element[i];
                }
                delete[] list->element;
                list->element = newelement;
                list->capital = list->capital * 2;
        }
        for (int j = list->size; j > i; j--) {
                list->element[j + 1] = list->element[i];
        }
        list->element[i] = value;
        list->size++;
}

template<typename T>
void deleteelement(sequentaillist<T>* list, int i) {                                //删除第i个元素
        if (list == nullptr) return;
        if (i<0 || i>list->size) {
                cout << "下标越界" << endl;
                return;
        }
        for (int j = i; j < list->size - 1; j++) {
                list->element[j] = list->element[j + 1];
        }
        list->size--;
}
template<typename T>
void remove(sequentaillist<T>* list, int value) {                                //删除表中的所有value
        if (list == nullptr) return;
        for (int i = 0; i < list->size; i++) {
                if (list->element[i] == value) {
                        deleteelement(list, i);                                                        
                        i--;                        //删除位置后因为所有元素都要向前一位,覆盖了原本的i号位置,所以i号位置重新比较一遍
                }
        }
}

template<typename T>
void setvalue(sequentaillist<T>* list, int i, int value) {                        //设置第i个元素的值
        if (list == nullptr) return;
        if (i<0 || i>list->size) {
                cout << "下标越界" << endl;
                return;
        }
        list->element[i] = value;
}
int main() {
        // 初始化线性表
        sequentaillist<int> list;
        initlist(&list, 5); // 初始容量为5
        cout << "初始化线性表,容量为5" << endl;

        // 插入元素
        insert(&list, 0, 10);
        insert(&list, 1, 20);
        insert(&list, 2, 30);
        cout << "插入元素后,线性表内容为:";
        for (int i = 0; i < list.size; i++) {
                cout << list.element[i] << " ";
        }
        cout << endl;

        // 查找元素
        int value = 20;
        int index = findelement(list, value);
        if (index != -1) {
                cout << "查找元素" << value << ",位置为:" << index << endl;
        }
        else {
                cout << "查找元素" << value << ",未找到" << endl;
        }

        // 删除元素
        deleteelement(&list, 1);
        cout << "删除第1个元素后,线性表内容为:";
        for (int i = 0; i < list.size; i++) {
                cout << list.element[i] << " ";
        }
        cout << endl;

        // 删除所有指定值的元素
        remove(&list, 30);
        cout << "删除所有值为30的元素后,线性表内容为:";
        for (int i = 0; i < list.size; i++) {
                cout << list.element[i] << " ";
        }
        cout << endl;

        // 设置元素值
        setvalue(&list, 0, 100);
        cout << "设置第0个元素值为100后,线性表内容为:";
        for (int i = 0; i < list.size; i++) {
                cout << list.element[i] << " ";
        }
        cout << endl;

        // 清空线性表
        clearlist(&list);
        cout << "清空线性表后,线性表大小为:" << getsize(list) << endl;

        // 销毁线性表
        destroylist(&list);
        cout << "销毁线性表" << endl;

        return 0;
}
//线性表--链式存储结构
#include <iostream>
using namespace std;

// 定义链表节点模板结构
template <typename T>
struct Node {
    T data; // 数据域
    Node<T>* next; // 指向下一个节点的指针
};

// 定义链表模板类
template <typename T>
class LinkedList {
private:
    Node<T>* head; // 头节点指针

public:
    // 构造函数
    LinkedList() : head(nullptr) {}

    // 析构函数
    ~LinkedList() {
        destroy(head); // 销毁链表
    }

    // 初始化链表
    void init() {
        head = new Node<T>; // 创建头节点
        head->next = nullptr;
    }

    // 判断链表是否为空
    bool isempty() const {
        return head->next == nullptr;
    }

    // 获取链表长度
    int getsize() const {
        int count = 0;
        Node<T>* current = head->next;
        while (current) {
            count++;
            current = current->next;
        }
        return count;
    }

    // 清空链表
    void clear() {
        destroy(head->next); // 销毁链表中的所有节点
        head->next = nullptr; // 重置头节点的next指针
    }

    // 插入元素
    bool insert(int index, const T& value) {
        if (index < 0) return false; // 索引不能为负

        Node<T>* current = head;
        int currentIndex = 0;

        // 找到插入位置的前一个节点
        while (current != nullptr && currentIndex < index) {
            current = current->next;
            currentIndex++;
        }

        if (current == nullptr) return false; // 索引超出链表范围

        // 创建新节点
        Node<T>* newNode = new Node<T>;
        newNode->data = value;
        newNode->next = current->next;
        current->next = newNode;

        return true;
    }

    // 删除元素
    bool remove(int index) {
        if (index < 0) return false; // 索引不能为负

        Node<T>* current = head;
        int currentIndex = 0;

        // 找到删除位置的前一个节点
        while (current->next != nullptr && currentIndex < index) {
            current = current->next;
            currentIndex++;
        }

        if (current->next == nullptr) return false; // 索引超出链表范围

        // 删除节点
        Node<T>* temp = current->next;
        current->next = temp->next;
        delete temp;

        return true;
    }

    // 查找元素
    int find(const T& value) const {
        Node<T>* current = head->next;
        int index = 0;

        while (current != nullptr) {
            if (current->data == value) {
                return index;
            }
            current = current->next;
            index++;
        }

        return -1; // 未找到
    }

    // 获取指定位置的元素
    bool getvalue(int index, T& value) const {
        if (index < 0) return false; // 索引不能为负

        Node<T>* current = head->next;
        int currentIndex = 0;

        while (current != nullptr && currentIndex < index) {
            current = current->next;
            currentIndex++;
        }

        if (current == nullptr) return false; // 索引超出链表范围

        value = current->data;
        return true;
    }

    // 设置指定位置的元素
    bool setvalue(int index, const T& value) {
        if (index < 0) return false; // 索引不能为负

        Node<T>* current = head->next;
        int currentIndex = 0;

        while (current != nullptr && currentIndex < index) {
            current = current->next;
            currentIndex++;
        }

        if (current == nullptr) return false; // 索引超出链表范围

        current->data = value;
        return true;
    }

    // 销毁链表
    void destroy(Node<T>*& head) {
        Node<T>* temp;
        while (head) {
            temp = head;
            head = head->next;
            delete temp;
        }
    }

    // 打印链表
    void print() const {
        Node<T>* current = head->next;
        while (current != nullptr) {
            cout << current->data << " ";
            current = current->next;
        }
        cout << endl;
    }

    //创建链表(头插法)
    void creatLnode_1(int n) {
        head = new Node<T>; // 创建头节点
        head->next = nullptr;

        Node<T>* p;
        for (int i = 0; i < n; i++) {
            p = new Node<T>; // 创建新节点
            cin >> p->data; // 从标准输入读取数据
            p->next = head->next; // 新节点指向头节点的下一个节点
            head->next = p; // 头节点指向新节点
        }
    }

    // 创建链表(尾插法)
    void creatLnode_2(int n) {
        head = new Node<T>; // 创建头节点
        head->next = nullptr;

        Node<T>* p, * r;
        r = head;
        for (int i = 0; i < n; i++) {
            p = new Node<T>; // 创建新节点
            cin >> p->data; // 从标准输入读取数据
            p->next = nullptr;
            r->next = p; // 将新节点链接到链表末尾
            r = p; // 更新尾指针
        }
    }

};

int main() {
    LinkedList<int> list;

    // 测试头插法创建链表
    cout << "使用头插法创建链表:" << endl;
    int n1;
    cout << "请输入链表的长度:";
    cin >> n1;
    list.creatLnode_1(n1);
    cout << "链表内容:";
    list.print();

    // 测试尾插法创建链表
    cout << "\n使用尾插法创建链表:" << endl;
    int n2;
    cout << "请输入链表的长度:";
    cin >> n2;
    list.clear(); // 清空链表
    list.creatLnode_2(n2);
    cout << "链表内容:";
    list.print();

    // 测试插入元素
    cout << "\n插入元素:" << endl;
    int index, value;
    cout << "请输入插入位置和值:";
    cin >> index >> value;
    if (list.insert(index, value)) {
        cout << "插入成功" << endl;
    }
    else {
        cout << "插入失败" << endl;
    }
    cout << "链表内容:";
    list.print();

    // 测试删除元素
    cout << "\n删除元素:" << endl;
    cout << "请输入删除位置:";
    cin >> index;
    if (list.remove(index)) {
        cout << "删除成功" << endl;
    }
    else {
        cout << "删除失败" << endl;
    }
    cout << "链表内容:";
    list.print();

    // 测试查找元素
    cout << "\n查找元素:" << endl;
    cout << "请输入要查找的值:";
    cin >> value;
    int foundIndex = list.find(value);
    if (foundIndex != -1) {
        cout << "元素" << value << "的位置为:" << foundIndex << endl;
    }
    else {
        cout << "元素" << value << "未找到" << endl;
    }

    // 测试获取指定位置的元素
    cout << "\n获取指定位置的元素:" << endl;
    cout << "请输入要获取的元素索引:";
    cin >> index;
    int retrievedValue;
    if (list.getvalue(index, retrievedValue)) {
        cout << "第" << index << "个元素的值为:" << retrievedValue << endl;
    }
    else {
        cout << "索引超出范围" << endl;
    }

    // 测试设置指定位置的元素
    cout << "\n设置指定位置的元素:" << endl;
    cout << "请输入要设置的元素索引和新值:";
    cin >> index >> value;
    if (list.setvalue(index, value)) {
        cout << "设置成功" << endl;
    }
    else {
        cout << "设置失败" << endl;
    }
    cout << "\n清空链表:" << endl;
    list.clear();
    cout << "清空链表后,链表是否为空:" << (list.isempty() ? "是" : "否") << endl;
    return 0;
}

//栈-顺序存储模式+应用案例
//注意:我这里初始化top=-1可以用,但是不符合数据结构老师的规范,不要写进实验报告里面
#include<iostream>
using namespace std;
template<typename T>
struct Sqstack {
        T* data;
        int top;
        int capacity;
};
template<typename T>
Sqstack<T>* initstack() {                        //初始化栈
        Sqstack<T> *s = new Sqstack<T>();
        if (s == nullptr) {
                cout << "内存分配失败" << endl;
                return nullptr;
        }
        s->data = new T[100];
        s->top = -1;
        s->capacity = 100;
        return s;
}

template<typename T>
void destroy(Sqstack<T>* s) {                        //销毁栈
        delete[] s->data;
        delete s;
}

template<typename T>
void push(Sqstack<T>* s, T num) {                        //入栈
        if (s->top == s->capacity-1) {                                                //扩容
                cout << "栈满,重新扩容" << endl;
                T* newdata = new T[2 * s->capacity];
                for (int i = 0; i < s->top; i++) {
                        newdata[i] = s->data[i];
                }
                delete[] s->data;
                s->data = newdata;
                s->capacity *= 2;
        }
        s->data[++s->top] = num;
}

template<typename T>
void pop(Sqstack<T>* s, T& e) {                        //出栈,并用e返回
        if (s->top == -1) {
                cout << "栈为空,删除失败" << endl;
                return;
        }
        e = s->data[s->top--];
}

template<typename T>
T gettop(Sqstack<T> s) {                        //获取栈顶元素
        if (s.top == -1) {
                cout << "栈为空,获取失败" << endl;
                return;
        }
        return s.data[s.top];
}

template<typename T>
bool isempty(Sqstack<T> s) {                        //判断栈是否为空
        return s.top == -1;
}

template<typename T>
void clear(Sqstack<T>* s) {                        //清空栈
        if (s == nullptr) {
                cout << "栈为空,清空失败" << endl;
                return;
        }
        s->top = -1;
}
template<typename T>
int length(Sqstack<T> s) {                        //获取栈的长度
        return s.top + 1;
}

template<typename T>
void prints(Sqstack<T> *s) {                    //打印栈中的元素
        if (s == nullptr) {
                cout << "空栈,打印失败" << endl;
                return;
        }
        for (int i = 0; i <= s->top; i++) {
                cout << s->data[i] << " ";
        }
        cout << endl;
}
//---------数值转换---------
void conversion(int N) {                        //输入一个非负十进制数,转化为8进制
        Sqstack<int>* s = initstack<int>();
        while (N) {
                push(s, N % 8);
                N /= 8;
        }
        int e = 0;
        while (!isempty(*s)) {
                pop(s, e);
                cout << e;
        }
        cout << endl;
}
//---括号算法的匹配---
bool validateBrackets(const string s) {
        int n = s.size();
        Sqstack<char>* stacks = initstack<char>();                //这里默认创建成功
        for (char c : s) {                      //加强型循环(也称for-each循环)
                switch (c) {
                        case '[':
                        case '{':
                        case '(': 
                                push(stacks, c); break;
                        case ')': {
                                char temp;
                                if (isempty(*stacks) || gettop(*stacks) != '(')
                                        return false;
                                pop(stacks, temp);
                                break;
                        }
                        case ']': {
                                char temp;
                                if (isempty(*stacks) || gettop(*stacks) != ']')
                                        return false;

                                pop(stacks, temp);
                                break;
                        }
                        case '}': {
                                char temp;
                                if (isempty(*stacks) || gettop(*stacks) != '}')
                                        return false;
                                pop(stacks, temp);
                                break;
                        }
                        default:
                                break;
                }
        }
        return isempty(*stacks);        //输入完s后判断栈类是否还有操作符
}
//--------行编辑程序-----------
void editline(string s) {
        Sqstack<char>* stacks = initstack<char>();                        //默认创建成功哈
        char ch, temp;
        cin >> ch;
        while (ch != EOF) {
                while (ch != '\n') {
                        switch (ch) {
                                case '#':pop(stacks, temp);                                //由于函数需要添加了temp
                                case '@':clear(stacks);
                                default:push(stacks, ch);
                        }
                        cin >> ch;
                }
                //这里需要一个函数将你的栈中元素上传到数据区

                //清空栈
                clear(stacks);
                if (ch != EOF) cin >> ch;
        }
        destroy(stacks);
}
//--------表达式求值-----------
int precedence(char op) {            // 定义操作符的优先级
        switch (op) {
        case '+':
        case '-':
                return 1;
        case '*':
        case '/':
                return 2;
        default:
                return 0;
        }
}
char precedences(char op1, char op2) {            // 比较两个操作符的优先级
        int p1 = precedence(op1);
        int p2 = precedence(op2);

        if (p1 > p2) {
                return '>';
        }
        else if (p1 < p2) {
                return '<';
        }
        else {
                return '=';
        }
}
int applyOp(int a, int b, char op) {                // 应用操作符
        switch (op) {
        case '+': return a + b;
        case '-': return a - b;
        case '*': return a * b;
        case '/':
                if (b == 0) throw runtime_error("Division by zero");
                return a / b;
        default:
                throw runtime_error("Invalid operator");
        }
}
int evaluateExpression() {                // 表达式求值
        stack<char> s1;  // 运算符栈
        stack<int> s2;   // 运算数栈

        s1.push('#');  // 初始符号

        char c;
        while (cin >> c) {
                if (isdigit(c)) {
                        s2.push(c - '0');  // 将字符转换为整数
                }
                else {
                        switch (precedences(s1.top(), c)) {
                        case '<': {
                                s1.push(c);
                                break;
                        }
                        case '=': {
                                s1.pop();
                                break;
                        }
                        case '>': {
                                char op = s1.top();
                                s1.pop();
                                int b = s2.top();
                                s2.pop();
                                int a = s2.top();
                                s2.pop();
                                s2.push(applyOp(a, b, op));
                                break;
                        }
                        }
                }
        }
        return s2.top();
}
int main() {
        Sqstack<int>* s = initstack<int>(); // 初始化栈
        if (s == nullptr) {
                cout << "初始化栈失败" << endl;
                return 1;
        }

        // 测试入栈
        cout << "测试入栈:" << endl;
        push(s, 10);
        push(s, 20);
        push(s, 30);
        prints(s); // 打印栈内容

        // 测试获取栈顶元素
        cout << "测试获取栈顶元素:" << endl;
        cout << "栈顶元素为:" << gettop(*s) << endl;

        // 测试出栈
        cout << "测试出栈:" << endl;
        int popElement;
        pop(s, popElement);
        cout << "出栈元素为:" << popElement << endl;
        prints(s); // 打印栈内容

        // 测试判断栈是否为空
        cout << "测试判断栈是否为空:" << endl;
        if (isempty(*s)) {
                cout << "栈为空" << endl;
        }
        else {
                cout << "栈不为空" << endl;
        }

        // 测试清空栈
        cout << "测试清空栈:" << endl;
        clear(s);
        prints(s); // 打印栈内容

        // 测试获取栈长度
        cout << "测试获取栈长度:" << endl;
        cout << "栈的长度为:" << length(*s) << endl;

        // 测试扩容
        cout << "测试扩容:" << endl;
        for (int i = 0; i < 150; i++) {
                push(s, i);
        }
        prints(s); // 打印栈内容

        // 销毁栈
        destroy(s);

        return 0;
}
//栈--链式存储结构
#include<iostream>
using namespace std;

template<typename T>
struct StackNode {                                        
        T data;        
        StackNode<T>* next;
};

template<typename T>
struct Linklist {
        StackNode<T>* top;
        int count;
};

template<typename T>
Linklist<T>* init() {                                                        //初始化
        Linklist<T>* s = new Linklist<T>();
        if (s == nullptr) {
                cout << "栈创建失败,呜呜呜" << endl;
                return nullptr;
        }
        s->top = nullptr;
        s->count = 0;
        return s;
}

template<typename T>
void destroy(Linklist<T>* s) {                                        //销毁
        if (s == nullptr) {
                cout << "栈指针为空,无需销毁" << endl;
                return;
        }
        StackNode<T>* current = s->top;
        while (current) {
                StackNode<T>* next = current->next;
                delete current;
                current = next;
        }
        delete s;
}

template<typename T>
void push(Linklist<T>* s, T data) {                                //入栈,栈的链式存储结构理论上来说没有容量限制,可以存储任意多个(只要内存够)
        if (s == nullptr) {
                cout << "栈指针为空,无需销毁" << endl;
                return;
        }
        StackNode<T>* temp = new StackNode<T>();
        temp->data = data;
        temp->next = s->top;
        s->top = temp;
        s->count++;
}

template<typename T>
void pop(Linklist<T>* s, T& e) {                                        //出栈
        if (s == nullptr) {
                cout << "栈指针为空" << endl;
                return;
        }
        if (s->top == nullptr) {
                cout << "空栈,无法出栈" << endl;
                return;
        }
        e = s->top->data;
        StackNode<T>* node = s->top;
        s->top = s->top->next;
        delete node;
}

template<typename T>
T gettop(Linklist<T>* s) {                                                        //获取栈顶元素
        if (s == nullptr) {
                cout << "栈指针为空" << endl;
                return T();                                                // 返回默认构造的T类型值,把该类型看成一个类
        }
        if (s->top == nullptr) {
                cout << "空栈,没有栈顶元素" << endl;
                return T();
        }
        return s->top->data;
}

template<typename T>
bool isempty(Linklist<T>* s) {                                                //判断栈空
        return s->top == nullptr;
}

template<typename T>
void clear(Linklist<T>* s) {                                                //清空栈
        if (s == nullptr) {
                cout << "栈指针为空" << endl;
                return;
        }
        if (s->top == nullptr) {
                cout << "空栈,无需清空" << endl;
                return;
        }
        cout << "清空栈中所有元素" << endl;
        StackNode<T>* current = s->top;
        while (current) {
                StackNode<T>* next = current->next;
                delete current;
                current = next;
        }
        s->top = nullptr;
        s->count = 0;
}

template<typename T>
int length(Linklist<T>* s) {                                                //返回栈中元素的长度
        if (s == nullptr) {
                cout << "栈指针为空" << endl;
                return 0;
        }
        int sum = 0;
        StackNode<T>* node = s->top;
        while (node) {
                sum++;
                node = node->next;
        }
        return sum;
}

template<typename T>
void prints(Linklist<T>* s) {                                                        //打印栈中元素
        if (s == nullptr) {
                cout << "栈指针为空" << endl;
                return;
        }
        if (s->top == nullptr) {
                cout << "空栈,无元素可打印" << endl;
                return;
        }
        cout << "栈中的元素为:";
        StackNode<T>* node = s->top;
        while (node) {
                cout << node->data << " ";
                node = node->next;
        }
        cout << endl; // 在函数末尾添加换行符
}

int main() {
        Linklist<int>* s = init<int>(); // 初始化栈
        if (s == nullptr) {
                cout << "初始化栈失败" << endl;
                return 1;
        }

        // 测试入栈
        cout << "测试入栈:" << endl;
        push(s, 10);
        push(s, 20);
        push(s, 30);
        prints(s); // 打印栈内容

        // 测试获取栈顶元素
        cout << "测试获取栈顶元素:" << endl;
        int topElement = gettop(s);
        cout << "栈顶元素为:" << topElement << endl;

        // 测试出栈
        cout << "测试出栈:" << endl;
        int popElement;
        pop(s, popElement);
        cout << "出栈元素为:" << popElement << endl;
        prints(s); // 打印栈内容

        // 测试判断栈是否为空
        cout << "测试判断栈是否为空:" << endl;
        if (isempty(s)) {
                cout << "栈为空" << endl;
        }
        else {
                cout << "栈不为空" << endl;
        }

        // 测试获取栈长度
        cout << "测试获取栈长度:" << endl;
        cout << "栈的长度为:" << length(s) << endl;

        // 测试清空栈
        cout << "测试清空栈:" << endl;
        clear(s);
        prints(s); // 打印栈内容

        // 再次测试获取栈长度
        cout << "测试获取栈长度:" << endl;
        cout << "栈的长度为:" << length(s) << endl;

        // 测试销毁栈
        cout << "测试销毁栈:" << endl;
        destroy(s);

        return 0;
}

队列

//队列--链式存储结构
#include<iostream>
using namespace std;
template<typename T>
struct Qnode {
        T data;
        Qnode<T>* next;
};

template<typename T>
struct QueueList {
        Qnode<T>* front;                        //队头指针,为了操作方便,front指向头结点
        Qnode<T>* rear;                         //队尾指针
};

template<typename T>
void initQueue(QueueList<T>* list) {                        //初始化队列
        if (list == nullptr) {
                cout << "空队列,无法初始化" << endl;
                return;
        }
        list->front = new Qnode<T>();
        if (list->front == nullptr) {
                cout << "内存分配失败" << endl;
                return;
        }
        list->front->next = nullptr;
        list->rear = list->front;
}

template<typename T>
void clearQueue(QueueList<T>* list) {                        //清空队列
        if (list == nullptr || list->front == nullptr) {
                return;
        }
        Qnode<T>* p = list->front->next;
        while (p != nullptr) {
                Qnode<T>* temp = p;
                p = p->next;
                delete temp;
        }
        list->front->next = nullptr;
        list->rear = list->front;
}

template<typename T>
void destroyQueue(QueueList<T>* list) {                        //销毁队列
        if (list == nullptr) return;
        clearQueue(list);
        delete list->front;                                                        //销毁和清空的区别
}

template<typename T>
bool queueEmpty(QueueList<T>* list) {
        if (list == nullptr || list->front == nullptr) {
                return true;
        }
        return list->front->next == nullptr;
}

template<typename T>
int queueLength(QueueList<T>* list) {
        if (list == nullptr || list->front == nullptr ) return 0;                //nullptr是c++风格的,相当于c里面的NULL
        int ans = 0;
        Qnode<T>* p = list->front->next;
        while (p) {
                ans++;
                p = p->next;
        }
        return ans;
}

template<typename T>
T getHead(QueueList<T>* list) {
        if (list == nullptr || list->front == nullptr || list->front->next == nullptr) {
                throw out_of_range("队列为空,无法获取队头元素");                //因为这里不好return ,所以我们可以抛出一个异常
        }
        return list->front->next->data;
}

template<typename T>
void enQueue(QueueList<T>* list, T data){
        if (list == nullptr || list->front == nullptr) {
                cout << "链表为空,无法入队" << endl;
                return;
        }

        Qnode<T>* p = new Qnode<T>();
        p->data = data;
        p->next = nullptr;

        if (list->front->next == nullptr) {                        //空队列
                list->front->next = p;
                list->rear = p;
        }
        else {
                list->rear->next = p;
                list->rear = p;
        }
}

template<typename T>
void deQueue(QueueList<T>* list, T& e) {
        if (list == nullptr || list->front == nullptr || list->front->next == nullptr) {
                cout << "空指针或者空队列,无法删除" << endl;
                return;
        }
        Qnode<T>* p = list->front->next;
        list->front->next = p->next;
        e = p->data;
        if (list->front->next == nullptr) list->rear = list->front;
        delete p;
}

template<typename T>
void printQueue(QueueList<T>* list) {
        if (list == nullptr || list->front == nullptr) {
                cout << "空队列" << endl;
                return;
        }
        cout << "队列中的元素为:";
        Qnode<T>* p = list->front->next;
        while (p) {
                cout << p->data << " ";
                p = p->next;
        }
        cout << endl;
}
int main() {
        QueueList<int> list;
        initQueue(&list);

        try {
                cout << "请输入元素个数:";
                int n;        cin >> n;
                cout << "请输入元素:";
                for (int i = 0; i < n; i++) {
                        int a;
                        cin >> a;
                        enQueue(&list, a);
                }
                printQueue(&list); // 打印队列

                int e;
                deQueue(&list, e);
                cout << "出队元素: " << e << endl;
                printQueue(&list); // 再次打印队列

                cout << "队头元素为:" << getHead(&list) << endl;

                deQueue(&list, e);
                cout << "出队元素: " << e << endl;
                printQueue(&list); // 再次打印队列
                cout << "队头元素为:" << getHead(&list) << endl;

                deQueue(&list, e);
                cout << "出队元素: " << e << endl;
                printQueue(&list); // 再次打印队列

                if (queueEmpty(&list)) {
                        cout << "队列为空" << endl;
                }

                destroyQueue(&list);
        }
        catch (const out_of_range& e) {
                cout << "错误: " << e.what() << endl;
        }

        return 0;
}
//队列--顺序存储结构
//由于如果单独普通队列意义不大,我们直接从循环队列开干
#include<bits/stdc++.h>
using namespace std;
const int MAX_SIZE = 1000;
template<typename T>
struct Squeue {
        T *data;
        int front, rear;
};

template<typename T>
void initSqueue(Squeue<T>* s) {
        s->data = new T[MAX_SIZE];
        if (s->data == nullptr) {
                cout << "内存分配失败" << endl;
                return;
        }
        s->front = s->rear = 0;
}

template<typename T>
int queueLength(Squeue<T>* s) {
        if (s == nullptr) {
                throw invalid_argument("队列对象为空");
        }
        return (s->rear - s->front + MAX_SIZE) % MAX_SIZE;
}

template<typename T>
void clearSqueue(Squeue<T>* s) {
        if (s == nullptr) {
                throw invalid_argument("队列对象为空,无法清空");
        }
        s->front = 0;
        s->rear = 0;
}

template <typename T>
void destroySqueue(Squeue<T>* s) {
        if (s == nullptr) {
                throw invalid_argument("队列对象为空,无法清空");
        }
        delete[] s->data;
        s->front = 0;
        s->rear = 0;
}

template<typename T>
bool squeueEmpty(Squeue<T>* s) {
        if (s == nullptr) throw std::invalid_argument("队列对象为空");
        return (s->rear - s->front + MAX_SIZE) % MAX_SIZE == 0;
}

template<typename T>
T getHead(Squeue<T>* s) {
        if (s == nullptr) throw std::invalid_argument("队列对象为空");
        if (s->front == s->rear) {
                throw out_of_range("空队列,无法获取首元素");
        }
        return s->data[s->front];
}

template<typename T>
void enSqueue(Squeue<T>* s, T data) {
        if (s == nullptr) throw std::invalid_argument("队列对象为空");
        if ((s->rear + 1) % MAX_SIZE == s->front)
                throw out_of_range("队列已满,无法继续扩充元素");
        s->data[s->rear] = data;
        s->rear = (s->rear + 1) % MAX_SIZE;
}

template<typename T>
void deSqueue(Squeue<T>* s, T& e) {
        if (s == nullptr) throw std::invalid_argument("队列对象为空");
        if (s->rear == s->front)
                throw out_of_range("队列为空,无法删除元素");
        e = s->data[s->front];
        s->front = (s->front + 1) % MAX_SIZE;
}
int main() {
    Squeue<int> s;
    int choice, data;

    try {
        // 初始化队列
        initSqueue(&s);
        cout << "队列初始化成功" << endl;

        while (true) {
            cout << "\n队列操作菜单:" << endl;
            cout << "1. 入队" << endl;
            cout << "2. 出队" << endl;
            cout << "3. 获取队头元素" << endl;
            cout << "4. 检查队列是否为空" << endl;
            cout << "5. 清空队列" << endl;
            cout << "6. 销毁队列并退出" << endl;
            cout << "请输入您的选择:";
            cin >> choice;

            switch (choice) {
            case 1: // 入队
                cout << "请输入要入队的元素:";
                cin >> data;
                enSqueue(&s, data);
                cout << "入队成功,当前队列长度为: " << queueLength(&s) << endl;
                break;
            case 2: // 出队
                if (squeueEmpty(&s)) {
                    cout << "队列为空,无法出队" << endl;
                }
                else {
                    deSqueue(&s, data);
                    cout << "出队元素: " << data << endl;
                    cout << "当前队列长度为: " << queueLength(&s) << endl;
                }
                break;
            case 3: // 获取队头元素
                if (squeueEmpty(&s)) {
                    cout << "队列为空,无法获取队头元素" << endl;
                }
                else {
                    data = getHead(&s);
                    cout << "队头元素为: " << data << endl;
                }
                break;
            case 4: // 检查队列是否为空
                if (squeueEmpty(&s)) {
                    cout << "队列为空" << endl;
                }
                else {
                    cout << "队列不为空,当前队列长度为: " << queueLength(&s) << endl;
                }
                break;
            case 5: // 清空队列
                clearSqueue(&s);
                cout << "队列已清空" << endl;
                break;
            case 6: // 销毁队列并退出
                destroySqueue(&s);
                cout << "队列已销毁,程序退出" << endl;
                return 0;
            default:
                cout << "无效的选择,请重新输入" << endl;
            }
            system("cls");              //清屏函数
        }
    }
    catch (const std::invalid_argument& e) {
        cout << "错误: " << e.what() << endl;
    }
    catch (const std::out_of_range& e) {
        cout << "错误: " << e.what() << endl;
    }

        return 0;
}  

//串的基本函数定义
//由于演示需要,混用了c++风格和c风格,如realloc和new、nullptr和NULL,自己编写时需要统一
//尤其要注意终止符'\0',c++中的字符串没有这个概念,c++的string类是一个对象,这里知识配合数据结构演示,c的话要注意
#include<bits/stdc++.h>
using namespace std;
const int MAXSIZE = 1000;
class string {                                        //我们还可以将size不单独出来,直接存放在data[0]里面
        char* data;
        int size;
        int capacity;
public:
        string() {
                data = new char[MAXSIZE];
                data[0] = '\0';
                capacity = MAXSIZE;
                size = 0;
        }                //构造函数
        // 下面的函数都来自于书上的抽象数据类型里面

        void StrAssign(const char *s) {
                //一开始想通过s.size()先去判断容量,但因为 const所以不能使用
                int i = 0;
                while (s[i] != '\0') {
                        data[size++] = s[i++];
                        if (i == capacity) {                        //扩容
                                char *newdata = new char[capacity * 2];
                                for (int j = 0; j < MAXSIZE; j++) {
                                        newdata[j] = data[j];
                                }
                                delete[] data;
                                data = newdata;
                                capacity *= 2;
                        }
                }
                data[size] = '\0';
        }

        void StrCopy(string& s) {                //copy
                int i = 0;
                while (s.data[i] != '\0') {
                        data[i] = s.data[i];
                        i++;
                }
                data[i] = '\0';
                size = i;
        }                        

        bool StrEmpty() {             // 判断是否为空串
                if (data[0] == '\0') return true;
                else return false;
        }

        int StrLength() {
                return size;
        }

        int StrCompare(string s) {
                char* p1 = data, * p2 = s.data;
                while (*p1 && *p2 && *p1 == *p2) {
                        p1++;
                        p2++;
                }
                return (*p1 > *p2) ? 1 : (*p1 < *p2) ? -1 : 0;
        }

        void clearstring() {
                while (*data != '\0') {
                        *data = '\0';
                        data++;
                }
                size = 0;
        }

        void concat(string s) {
                while (!s.StrEmpty()) {
                        data[size] = *s.data;
                        s.data++;
                        size++;
                        if (size == capacity) {
                                char* newdata = new char[capacity * 2];
                                for (int i = 0; i < capacity; i++) {
                                        newdata[i] = data[i];
                                }
                                delete[] data;
                                data = newdata;
                                capacity *= 2;
                        }
                }
                data[size] = '\0';
        }

        string Substring(int pos, int len) {
                string s;
                if (pos < 0 || pos > size - len) return s;
                int i = 0;
                while (i < len ) {
                        s.data[i] = data[pos + i];
                        if (i == s.capacity) {
                                char* newdata = new char[s.capacity * 2];
                                for (int j = 0; j < s.capacity; j++) {
                                        newdata[i] = s.data[i];
                                }
                                delete[] s.data;
                                s.data = newdata;
                                s.capacity *= 2;
                        }
                        i++;
                }
        }

        int index(string s, int pos = 0) {
                if (pos < 0 || pos >= size) return -1;
                for (int i = pos; i < size; i++) {
                        if (data[i] == s.data[0]) {
                                int j = 0;
                                while (j < s.size){
                                        if (data[i + j] == s.data[j]) j++;
                                        else break;
                                }
                                if (j == s.size) return i;
                        }
                }
                return -1;
        }
        string replace(string x, string y, int pos = 0) {                                
                string result;
                if (pos < 0 || pos >= size || x.size == 0) return result;
                int current = pos;
                while (true) {
                        int match_pos = index(x, current );
                        if (match_pos == -1) break;
                        //拼接字符串段
                        string temp = Substring(current, match_pos - current);
                        result.concat(temp);
                        result.concat(y);
                        //更新参数
                        current = match_pos + x.size;
                }
                string temp = Substring(current, size - current);
                result.concat(temp);
                return result;
        }                        //替换

        void Strinsert(int pos, string s) {
                if (pos < 0 || pos > size) return;
                int i = 0;
                if (size + s.size >= capacity) {
                        data = (char*)realloc(data, (size + s.size + 1) * sizeof(char));        //通过c语言的realloc函数实现精确扩容,需要添加头文件stdlib.h
                        if (data == nullptr) {                                                                                                //当然如果为了避免反复扩容可以一次多分配一些内存
                                cout << "内存分配失败" << endl;
                                return;
                        }
                        capacity = size + s.size + 1;
                }
                for (int i = size - 1; i >= pos; i--) {                //腾出位置给新字符串
                        data[i + s.size] = data[i];
                }
                for (int i = 0; i < s.size; i++) {
                        data[pos + i] = s.data[i];
                 }
                size += s.size;
        }

        void Strdelete(int pos, int len) {
                if (pos < 0 || pos >= size - len || len <= 0) return;
                for (int i = pos; i < size - len; i++) {
                        data[i] = data[i + len];
                }
                data[size - len] = '\0';
                size -= len;
        }

        int findChar(char c, int pos = 0) {
                if (pos < 0 || pos >= size) return -1;
                for (int i = pos; i < size; i++) {
                        if (data[i] == c) return i;
                }
                return -1;
        }

        void reverse() {
                int left = 0, right = size - 1;
                while (left < right) {
                        char temp = data[left];
                        data[left] = data[right];
                        data[right] = temp;
                        left++;
                        right--;
                }
        }

        void destroy() {
                delete[] data;
                data = nullptr;
                size = 0;
        }
        
};
int main() {
        //测试代码直接用string会和系统的string冲突
                //解决方法1
        ::string s;   //通过::指定使用自定义的string类
        std::string s;                //系统string 类
                //解决方法2
        //重定义我的类名,不要冲突
        return 0;
}
//暴力搜索算法和KMP模式匹配算法
#include<bits/stdc++.h>
using namespace std;
//暴力搜索算法
int bf(string s, string pattern, int pos = 0) {
        if (pos < 0 || pos > s.length() || pattern.length() > s.length()) return -1;
        if (pattern.length() == 0) return 0;
        for (int i = pos; i < s.length() - pattern.length(); i++) {
                int temp = i, j = 0;
                for (; j < pattern.length(); j++) {
                        if (s[temp] == pattern[j]) {
                                temp++;        
                        }
                        else {
                                break;
                        }
                }
                if (j == pattern.length()) {
                        return i;
                }
        }
        return -1;
}
//更新前的回溯函数
void get_next(string pattern, int*& next) {
        int len = pattern.length();
        next = new int[len];  
        next[0] = -1;         

        int i = 0;    
        int j = -1;   

        while (i < len - 1) {  // 确保i+1不越界
                if (j == -1 || pattern[i] == pattern[j]) {
                        i++;
                        j++;
                        next[i] = j;  
                }
                else {
                        j = next[j];  
                }
        }
}
//更新后的回溯函数
void get_nextval(string pattern, int*& nextval) {
        int i = 0, j = -1;
        int len = (int)pattern.length();
        nextval = new int[len];
        nextval[0] = -1;
        while (i < len - 1) {
                if (j == -1 || pattern[i] == pattern[j]) {
                        i++; j++;
                        if (pattern[i] != pattern[j]) nextval[i] = j;
                        else nextval[i] = nextval[j];
                }
                else j = nextval[j];
        }
}
//KMP模式匹配算法
int kmp(string s, string pattern, int pos = 0) {
        int s_len = (int)s.length();
        int p_len = (int)pattern.length();
        if (pos < 0 || pos > s_len || p_len > s_len) return -1;
        if (pattern.empty()) return 0;
        int* next = nullptr;
        get_next(pattern, next);
        int i = pos, j = -1;
        while (i < s_len && j < p_len) {
                if ( j == -1 || s[i] == pattern[j]) {                                                                
                        i++; j++;
                }
                else {
                        j = next[j];
                }
        }
        delete[] next;
        return (j == p_len) ? (i - j) : -1;
}
int main() {
        string aa = "dfjkdfd";
        string pattern = "jkd";
        cout << kmp(aa, pattern, 0);
        return 0; 
}

广义表

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define MAX_STR_LEN 1024  //定义最大字符串长度
typedef char* AtomType;//定义原子类型为字符指针
typedef enum { ATOM, LIST } ElemTag;
typedef struct GLNode 
{
    ElemTag tag;  //节点类型标记(ATOM或LIST)
    union 
    {
        AtomType atom;  //原子节点值
        struct 
        {
            struct GLNode* hp;  //表头指针
            struct GLNode* tp;  //表尾指针
        } ptr;
    };
} GLNode, * GList;
//去除字符串中的所有空格
void remove_spaces(char* str) 
{
    if (!str) return;  //安全检查
    char* p = str, * q = str;
    while (*p) 
    {
        if (!isspace(*p)) *q++ = *p;  //只保留非空格字符
        p++;
    }
    *q = '\0';  //添加字符串结束符
}
//判断字符串类型:空表('N')、原子串('E')或其他形式('O')
char test(const char* s)
{
    if (!s || s[0] == '\0') return 'N';  //空指针或空串
    for (int i = 0; s[i]; i++)
    {
        if (s[i] == '(' || s[i] == ')' || s[i] == ',')
            return 'O';  //包含括号或逗号
    }
    return 'E';  //纯原子字符串
}
//获取子串中的第一项
void hsub(const char* s, char* h)
{
    int level = 0;  //括号嵌套层级计数器
    const char* p = s;
    char* q = h;
    while (*p) 
    {
        if (*p == '(') level++;       //遇到左括号增加层级
        else if (*p == ')') level--;  //遇到右括号减少层级
        else if (*p == ',' && level == 0) break;  //顶层逗号分割点
        *q++ = *p++;  //复制字符
    }
    *q = '\0';  //结束字符串
}
//获取子串中除第一项外的剩余部分
void tsub(const char* s, char* t)
{
    int level = 0;
    const char* p = s;
    char* q = t;
    while (*p) 
    {
        if (*p == '(') level++;
        else if (*p == ')') level--;
        else if (*p == ',' && level == 0) 
        {
            p++;  //跳过分割逗号
            break;
        }
        p++;
    }
    while (*p) *q++ = *p++;  //复制剩余部分
    *q = '\0';
}
//创建空表节点
GList CreateGList()
{
    GList L = (GList)malloc(sizeof(GLNode));
    if (!L) return NULL;
    L->tag = LIST;          //标记为列表类型
    L->ptr.hp = L->ptr.tp = NULL;  //初始化表头表尾为空
    return L;
}
//递归构建广义表
GList BuildGList(const char* s) 
{
    if (!s || strlen(s) == 0 || strcmp(s, "()") == 0)//处理空表情况
        return CreateGList();
    char type = test(s);
    if (type == 'N') return CreateGList();
    if (type == 'E') //处理原子节点
    {
        GList L = (GList)malloc(sizeof(GLNode));
        L->tag = ATOM;
        L->atom = _strdup(s);  //复制原子字符串
        return L;
    }
    char* content = _strdup(s);//处理列表情况
    if (content[0] == '(' && content[strlen(content) - 1] == ')') //去掉外层括号
    {
        content[strlen(content) - 1] = '\0';
        memmove(content, content + 1, strlen(content));
    }
    GList L = CreateGList();  //创建列表节点
    if (!L) return NULL;
    GList* current = &(L->ptr.hp);  //当前插入位置指针
    char* rest = _strdup(content);  //剩余待处理字符串
    while (strlen(rest) > 0) //分割出当前项和剩余部分
    {
        char* h = (char*)malloc(strlen(rest) + 1);
        char* t = (char*)malloc(strlen(rest) + 1);
        hsub(rest, h);
        tsub(rest, t);
        GList node = (GList)malloc(sizeof(GLNode));//创建新节点并构建子表
        node->tag = LIST;
        node->ptr.hp = BuildGList(h);  //递归构建子表
        node->ptr.tp = NULL;
        *current = node;//将新节点链接到当前列表
        current = &(node->ptr.tp);  //移动当前指针
        free(rest);
        rest = _strdup(t);
        free(h);
        free(t);
    }
    free(rest);
    free(content);
    return L;
}
//获取表头指针
GList GetHead(GList L) 
{
    if (!L || L->tag != LIST) return NULL;
    return L->ptr.hp ? L->ptr.hp->ptr.hp : NULL;
}
//获取表尾指针
GList GetTail(GList L)
{
    if (!L || L->tag != LIST) return NULL;
    if (!L->ptr.hp || !L->ptr.hp->ptr.tp) return NULL;
    GList tail = (GList)malloc(sizeof(GLNode));    //创建新节点表示表尾
    tail->tag = LIST;
    tail->ptr.hp = L->ptr.hp->ptr.tp;  //表尾作为新表头
    tail->ptr.tp = NULL;
    return tail;
}
//递归释放广义表内存
void FreeGList(GList L) 
{
    if (!L) return;
    if (L->tag == ATOM)
        free(L->atom);  //释放原子字符串
    else 
    {
        FreeGList(L->ptr.hp);  //递归释放表头
        FreeGList(L->ptr.tp);  //递归释放表尾
    }
    free(L);  //释放节点本身
}
//递归打印广义表
void PrintGList(GList L)
{
    if (!L) 
    {
        printf("()");  //空指针打印空表
        return;
    }
    if (L->tag == ATOM)
    {
        printf("%s", L->atom);  //原子直接打印
        return;
    }
    printf("(");// 列表打印
    GList p = L->ptr.hp;
    while (p)
    {
        PrintGList(p->ptr.hp);  //递归打印表头
        if (p->ptr.tp) printf(",");  //元素间用逗号分隔
        p = p->ptr.tp;  //移动到下一个元素
    }
    printf(")");
}
int main() 
{
    char input[MAX_STR_LEN] = { 0 };  //输入缓冲区
    char buffer[MAX_STR_LEN];         //临时缓冲区
    char operations[MAX_STR_LEN];     //操作序列缓冲区
    printf("请输入广义表(可以多行输入,以空行结束):\n");//读取多行输入直到空行
    while (fgets(buffer, MAX_STR_LEN, stdin))
    {
        if (buffer[0] == '\n') break;
        strcat(input, buffer);
    }
    remove_spaces(input); 
    GList L = BuildGList(input);
    if (!L) 
    {
        printf("错误: 构建广义表失败,请检查格式\n");
        return 1;
    }
    printf("构建的广义表为: ");
    PrintGList(L);
    printf("\n");
    printf("请输入操作序列(h表示head,t表示tail,例如tth): ");
    if (!fgets(operations, MAX_STR_LEN, stdin))
    {
        FreeGList(L);
        return 1;
    }
    operations[strcspn(operations, "\n")] = '\0';
    GList current = L;
    printf("操作过程:\n");
    if (strlen(operations) == 0) 
    {
        PrintGList(current);
        printf("\n");
    }
    else
    {
        for (int i = 0; operations[i]; i++) 
        {
            if (operations[i] == 'h') 
            {
                current = GetHead(current);
                printf("h -> ");
            }
            else if (operations[i] == 't')
            {
                current = GetTail(current);
                printf("t -> ");
            }
            else 
            {
                printf("错误: 无效操作 '%c'\n", operations[i]);
                FreeGList(L);
                return 1;
            }
            if (!current) 
            {
                printf("NULL\n");
                break;
            }
            PrintGList(current);
            printf("\n");
        }
    }
    FreeGList(L);
    return 0;
}

  • 二叉树
//二叉树结构
//树的结构一般都是用递归的思想来实现的
#include<stdio.h>
#include<stdlib.h>                //malloc的头文件
typedef struct BiTNode {
        int data;                                //如果需要可以改为其他类型数据如char类型
        struct BiTNode* lchild, * rchild;
}BiTNode,*BiTree;
int CreateBiTree(BiTree* T) {                //创建二叉树
        int x;
        scanf("%d", &x);
        if (x == 0) {    //0表示空结点
                T == NULL;
        }
        else {
                *T = (BiTree)malloc(sizeof(BiTNode));
                if (!*T) {
                        printf("内存分配失败\n");
                        return 0;
                }
                (*T)->data = x;
                CreateBiTree(&(*T)->lchild);        //递归创建左子树
                CreateBiTree(&(*T)->rchild);        //递归创建右子树
        }
        return 1;
}
//先序遍历
int PreOrderTraverse(BiTree T) {
        if (T == NULL) {
                return 0;
        }
        printf("%d ", T->data);        //访问根结点
        PreOrderTraverse(T->lchild);        //遍历左子树
        PreOrderTraverse(T->rchild);        //遍历右子树
        return 1;
}
//中序遍历
int InOrderTraverse(BiTree T) {
        if (T == NULL) {
                return 0;
        }
        InOrderTraverse(T->lchild);        //遍历左子树
        printf("%d ", T->data);        //访问根结点
        InOrderTraverse(T->rchild);        //遍历右子树
        return 1;
}
//后序遍历
int PostOrderTraverse(BiTree T) {
        if (T == NULL) {
                return 0;
        }
        InOrderTraverse(T->lchild);        //遍历左子树
        InOrderTraverse(T->rchild);        //遍历右子树
        printf("%d ", T->data);        //访问根结点
        return 1;
} 
//非递归思想先序遍历(栈)
int PreOrderTraverseStack(BiTree T) {
        if (T == NULL) {
                return 0;
        }
        BiTree stack[100];        //栈
        int top = -1;        //栈顶指针
        stack[++top] = T;        //将根结点入栈
        while (top != -1) {        //栈不空
                BiTree p = stack[top--];        //出栈
                printf("%d ", p->data);        //访问结点
                if (p->rchild) {        //如果有右子树
                        stack[++top] = p->rchild;        //入栈
                }
                if (p->lchild) {        //如果有左子树
                        stack[++top] = p->lchild;        //入栈
                }
        }
        return 1;
}
//层序遍历
int LevelOrderTraverse(BiTree T) {
        if (T == NULL) {
                return 0;
        }
        BiTree queue[100];        //队列
        int front = 0, rear = 0;        //队头和队尾指针
        queue[rear++] = T;        //将根结点入队
        while (front != rear) {        //队列不空
                BiTree p = queue[front++];        //出队
                printf("%d ", p->data);        //访问结点
                if (p->lchild) {        //如果有左子树
                        queue[rear++] = p->lchild;        //入队
                }
                if (p->rchild) {        //如果有右子树
                        queue[rear++] = p->rchild;        //入队
                }
        }
        return 1;
}
//求二叉树的深度
int Depth(BiTree T) {
        if (T == NULL) {
                return 0;
        }
        int ldepth = Depth(T->lchild);        //左子树深度
        int rdepth = Depth(T->rchild);        //右子树深度
        return (ldepth > rdepth ? ldepth : rdepth) + 1;        //返回较大值加1
}
//求二叉树的结点数
int CountNode(BiTree T) {
        if (T == NULL) {
                return 0;
        }
        return CountNode(T->lchild) + CountNode(T->rchild) + 1;        //返回左子树结点数加右子树结点数加1
}
//求二叉树的叶子结点数
int CountLeaf(BiTree T) {
        if (T == NULL) {
                return 0;
        }
        if (T->lchild == NULL && T->rchild == NULL) {        //如果是叶子结点
                return 1;
        }
        return CountLeaf(T->lchild) + CountLeaf(T->rchild);        //返回左子树叶子结点数加右子树叶子结点数
}
int main() {

        return 0;
}
  • 二叉线索树(以中序遍历为例)
#include <stdio.h>
#include <stdlib.h>

typedef enum PointerTag { Link, Thread };
typedef struct BiThrNode {
    int data;
    struct BiThrNode* lchild, * rchild;
    PointerTag Ltag, Rtag;
} BiThrNode, * BiThrTree;

void CreateBiTree(BiThrTree* T) {
    int x;
    scanf_s("%d", &x); // 使用scanf_s需根据编译器调整
    if (x == 0) {
        *T = NULL;
    }
    else {
        *T = (BiThrNode*)malloc(sizeof(BiThrNode));
        if (*T == NULL) {
            printf("内存分配失败\n");
            return;
        }
        (*T)->data = x;
        (*T)->Ltag = Link; // 初始化标签
        (*T)->Rtag = Link;
        CreateBiTree(&(*T)->lchild);
        CreateBiTree(&(*T)->rchild);
    }
}

void InOrderThread(BiThrTree* p, BiThrNode** pre) {
    if (*p != NULL) {
        InOrderThread(&(*p)->lchild, pre);
        // 处理当前节点的前驱线索
        if ((*p)->lchild == NULL) {
            (*p)->Ltag = Thread;
            (*p)->lchild = *pre;
        }
        // 处理前驱节点的后继线索
        if (*pre != NULL && (*pre)->rchild == NULL) {
            (*pre)->Rtag = Thread;
            (*pre)->rchild = *p;
        }
        *pre = *p; // 更新前驱
        InOrderThread(&(*p)->rchild, pre);
    }
}

void InOrderTraverseThread(BiThrNode* root) {
    BiThrNode* p = root;
    while (p != NULL) {
        // 找到最左节点
        while (p->Ltag == Link) {
            p = p->lchild;
        }
        printf("%d ", p->data);
        // 沿后继访问
        while (p->Rtag == Thread && p->rchild != NULL) {
            p = p->rchild;
            printf("%d ", p->data);
        }
        p = p->rchild; // 处理右子树
    }
}

int main() {
    BiThrTree root = NULL;
    printf("请输入二叉树的节点数据(0表示空节点,前序遍历方式):\n");
    CreateBiTree(&root);

    BiThrNode* pre = NULL;
    InOrderThread(&root, &pre);

    // 处理最后一个节点的后继线索
    if (pre != NULL) {
        pre->Rtag = Thread;
        pre->rchild = NULL;
    }

    printf("中序线索二叉树的中序遍历结果:\n");
    InOrderTraverseThread(root);
    printf("\n");

    return 0;
}
  • 树的结构及树转化为二叉树(以第三种树存储方式为例)
//树的存储结构
#include<stdio.h>
#include<stdlib.h>
#define MAX_SIZE 100
/*
        双亲表示法
        用一维数组的方式存储树结构,每个元素有两个属性,data和parent
        通过data表示该点的值,通过parent表示该点的父节点
*/
typedef struct PTNode {                //结点结构定义
        int data;
        int parent;
}PTNode;
typedef struct PTree {                //树的存储结构
        PTNode nodes[MAX_SIZE];
        int r,n;                                //根的位置和结点数
}PTree;

/*
        孩子表示法
        同样使用一维数组的方式存储树结构,每个元素有两个属性,data和firstchild
        firstchild表示该点的第一个孩子结点,孩子结点用链表的方式存储
*/
typedef struct CTNode {
        int child;
        struct CTNode* next;                
}*ChildPtr;
typedef struct CTBox {
        int data;
        ChildPtr firstchild;
}CTBox;
typedef struct CTree {
        CTBox nodes[MAX_SIZE];
        int n, r;                                //结点数,根的位置
}*CTree;

/*
        孩子兄弟表示法
*/
typedef struct CSNode {
        int data;
        struct CSNode* firstchild, * nextsibling;
}CSNode,*CSTree;

// ------------------------------------
typedef struct BiTNode {                //补充的二叉树的定义
        int data;
        struct BiTNode* lchild;
        struct BiTNode* rchild;
} BiTNode, * BiTree;
// 创建二叉树节点
BiTNode* createBiTreeNode(int data) {
    BiTNode* newNode = (BiTNode*)malloc(sizeof(BiTNode));
    if (!newNode) {
        printf("内存分配失败\n");
        return NULL;
    }
    newNode->data = data;
    newNode->lchild = NULL;
    newNode->rchild = NULL;
    return newNode;
}

// 树转换为二叉树
BiTree treeToBinaryTree(CSTree root) {
    if (root == NULL) {
        return NULL;
    }
    BiTree binaryRoot = createBiTreeNode(root->data);
    if (root->firstchild) {
        binaryRoot->lchild = treeToBinaryTree(root->firstchild);
    }
    CSNode* sibling = root->nextsibling;
    while (sibling) {
        BiTNode* newNode = createBiTreeNode(sibling->data);
        newNode->lchild = sibling->firstchild ? treeToBinaryTree(sibling->firstchild) : NULL;
        newNode->rchild = sibling->nextsibling ? treeToBinaryTree(sibling->nextsibling) : NULL;
        if (binaryRoot->rchild) {
            BiTNode* temp = binaryRoot->rchild;
            while (temp->rchild) {
                temp = temp->rchild;
            }
            temp->rchild = newNode;
        }
        else {
            binaryRoot->rchild = newNode;
        }
        sibling = sibling->nextsibling;
    }
    return binaryRoot;
}
int main() {

        return 0;
}
  • 构建哈夫曼树
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>

// 定义哈夫曼树的节点结构
typedef struct {
    int weight;       // 节点的权重
    int parent, lchild, rchild; // 父节点、左孩子节点、右孩子节点的索引
} HTNode, * HuffmanTree;

// 定义哈夫曼编码的类型为字符指针数组
typedef char** HuffmanCode;

// 从给定的n个节点中选择两个parent为0且weight最小的节点
void Select(HuffmanTree HT, int n, int* s1, int* s2) {
    int min1 = INT_MAX, min2 = INT_MAX;
    for (int i = 1; i <= n; i++) {
        if (HT[i].parent == 0) { // 找到没有被选择过的节点
            if (HT[i].weight < min1) {
                min2 = min1;
                *s2 = *s1;
                min1 = HT[i].weight;
                *s1 = i;
            }
            else if (HT[i].weight < min2) {
                min2 = HT[i].weight;
                *s2 = i;
            }
        }
    }
}

// 创建哈夫曼树并生成哈夫曼编码
void HuffmanCreate(HuffmanTree* HT, HuffmanCode* HC, int* w, int n) {
    if (n <= 1) return; // 如果只有一个字符,则不需要编码
    int m = 2 * n - 1; // 哈夫曼树的总节点数
    *HT = (HuffmanTree)malloc((m + 1) * sizeof(HTNode)); // 动态分配哈夫曼树数组
    for (int i = 1; i <= n; i++) {
        (*HT)[i].weight = w[i - 1]; // 初始化叶子节点的权重
        (*HT)[i].parent = 0;
        (*HT)[i].lchild = 0;
        (*HT)[i].rchild = 0;
    }
    for (int i = n + 1; i <= m; i++) {
        (*HT)[i].weight = 0;
        (*HT)[i].parent = 0;
        (*HT)[i].lchild = 0;
        (*HT)[i].rchild = 0;
    }

    // 构建哈夫曼树
    for (int i = n + 1; i <= m; i++) {
        int s1, s2;
        Select(*HT, i - 1, &s1, &s2); // 选择两个最小权重的节点
        (*HT)[s1].parent = i;
        (*HT)[s2].parent = i;
        (*HT)[i].lchild = s1;
        (*HT)[i].rchild = s2;
        (*HT)[i].weight = (*HT)[s1].weight + (*HT)[s2].weight; // 设置新节点的权重
    }

    *HC = (HuffmanCode)malloc((n + 1) * sizeof(char*)); // 动态分配哈夫曼编码数组
    char* cd = (char*)malloc(n * sizeof(char)); // 临时数组存储单个编码
    for (int i = 1; i <= n; i++) {
        int start = n - 1;
        for (int c = i, f = (*HT)[i].parent; f != 0; c = f, f = (*HT)[f].parent) {
            cd[--start] = ((*HT)[f].lchild == c) ? '0' : '1'; // 从根到叶子逆向生成编码
        }
        (*HC)[i] = (char*)malloc((n - start) * sizeof(char)); // 分配空间存储编码
        strcpy_s((*HC)[i], n - start + 1, &cd[start + 1]); // 复制编码到HC数组
    }
    free(cd); // 释放临时数组
}

int main() {
    
}

  • 图的邻接矩阵存储
#include<bits/stdc++.h>
using namespace std;
#define MAX_VERTEX_NUM 20
typedef struct  {
        char vexs[MAX_VERTEX_NUM]; // 顶点向量
        int arcs[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; // 邻接矩阵
        int vexnum, arcnum; // 图的当前顶点数和弧数
}MGraph;
int Locate(MGraph G, char v) {
        for (int i = 0; i < G.vexnum; i++) {
                if (G.vexs[i] == v) {
                        return i;
                }
        }
        return -1;
}
int CreateGraph(MGraph& G) {
        printf("请输入顶点数和边数:\n");
        cin >> G.vexnum >> G.arcnum;
        if (G.vexnum <= 0 || G.vexnum > MAX_VERTEX_NUM) {
                printf("输入错误!\n");
                return 0;
        }

        printf("请输入顶点信息:\n");
        for (int i = 0; i < G.vexnum; i++) {
                cin >> G.vexs[i];
        }

        printf("请输入边的信息:<边1><边2><权值>\n");
        for (int i = 0; i < G.vexnum; i++) {
                for (int j = 0; j < G.vexnum; j++) {
                        G.arcs[i][j] = INT_MAX;                        //初始化为无穷大
                }
        }
        for (int i = 0; i < G.arcnum; i++) {
                char v1, v2;
                int w;
                cin >> v1 >> v2 >> w;        //输入边的两个顶点和权值
                int p1 = Locate(G, v1);
                int p2 = Locate(G, v2);
                if (p1 == -1 || p2 == -1) {
                        printf("顶点信息输入错误\n");
                        return 0;
                }
                G.arcs[p1][p2] = w;
                G.arcs[p2][p1] = w;
        }
        printf("无向图创建成功!\n");
        return 1;
}
void PrintGraph(MGraph G) {
        printf("图的顶点信息为:\n");
        for (int i = 0; i < G.vexnum; i++) {
                printf("%c ", G.vexs[i]);
        }
        printf("\n图的邻接矩阵为:\n");
        for (int i = 0; i < G.vexnum; i++) {
                for (int j = 0; j < G.vexnum; j++) {
                        if (G.arcs[i][j] == INT_MAX) {
                                printf("∞ ");
                        }
                        else {
                                printf("%d ", G.arcs[i][j]);
                        }
                }
                printf("\n");
        }
}
int main() {
        MGraph G;
        if (CreateGraph(G)) {
                PrintGraph(G);
        }
        else {
                printf("图创建失败!\n");
        }
        return 0;
}
  • 图的邻接表存储
#include<bits/stdc++.h>
using namespace std;
#define MAX_VERTEX_NUM 20
typedef struct ArcNode {                // 弧结点
        int adjvex; // 弧头下标
        struct ArcNode* nextarc;
        int weight; // 权值
}ArcNode;
typedef struct VNode {                        //顶点结点
        char data;
        struct ArcNode* firstarc;
}VNode,AdjList[MAX_VERTEX_NUM];
typedef struct {                                //图
        AdjList vertices; // 顶点向量
        int vexnum, arcnum; // 图的当前顶点数和弧数
}AlGraph;
int Locate(AlGraph G, char v) {        // 查找顶点下标
        for (int i = 0; i < G.vexnum; i++) {
                if (G.vertices[i].data == v) {
                        return i;
                }
        }
        return -1;
}
int CreateGraph(AlGraph& G) {
        printf("请输入顶点数和边数:\n");
        cin >> G.vexnum >> G.arcnum;
        if (G.vexnum <= 0 || G.vexnum > MAX_VERTEX_NUM) {
                printf("输入错误!\n");
                return 0;
        }

        printf("请输入顶点信息:\n");                // 初始化
        for (int i = 0; i < G.vexnum; i++) {                
                cin >> G.vertices[i].data;
                G.vertices[i].firstarc = nullptr; 
        }

        printf("请输入边的信息:<边1><边2><权值>\n");
        for (int i = 0; i < G.arcnum; i++) {
                char v1, v2;
                int w;
                cin >> v1 >> v2 >> w; // 输入边的两个顶点
                int p1 = Locate(G, v1); // 查找顶点下标
                int p2 = Locate(G, v2);

                if (p1 == -1 || p2 == -1) {
                        printf("顶点信息输入错误\n");
                        return 0;
                }

                // 创建弧结点
                ArcNode* newArc = new ArcNode;
                newArc->weight = w;
                newArc->adjvex = p2;
                newArc->nextarc = G.vertices[p1].firstarc;        //尾插
                G.vertices[p1].firstarc = newArc;

                newArc = new ArcNode; // 创建另一条弧
                newArc->weight = w;
                newArc->adjvex = p1;
                newArc->nextarc = G.vertices[p2].firstarc;
                G.vertices[p2].firstarc = newArc;
        }
        printf("无向图创建成功!\n");
        return 1;
}
void PrintfGraph(AlGraph G) {
        printf("图的顶点信息为:\n");
        for (int i = 0; i < G.vexnum; i++) {
                cout << G.vertices[i].data << " ";
        }
        printf("\n图的邻接表为:\n");
        for (int i = 0; i < G.vexnum; i++) {
                cout << G.vertices[i].data << " -> ";
                ArcNode* p = G.vertices[i].firstarc;
                while (p) {
                        cout << G.vertices[p->adjvex].data << "(" << p->weight << ") ";
                        p = p->nextarc;
                }
                cout << endl;
        }
}
bool visited[MAX_VERTEX_NUM];
void DFS(AlGraph G, int v) {                        //dfs深度优先遍历
        visited[v] = true; // 访问标记
        cout << G.vertices[v].data << " "; // 访问顶点
        ArcNode* p = G.vertices[v].firstarc;
        while (p != NULL) {
                if (!visited[p->adjvex]) { // 如果未访问
                        DFS(G, p->adjvex); // 递归访问
                }
                p = p->nextarc; // 访问下一个邻接点
        }
}
void DFSTraverse(AlGraph G) {
        for (int i = 0; i < G.vexnum; i++) visited[i] = false; // 初始化
        for (int i = 0; i < G.vexnum; i++) {
                if (!visited[i]) {
                        DFS(G, i);
                        cout << endl; // 每个连通分量后换行
                }
        }

}
void BFS(AlGraph G, int v) {
        queue<int> q;
        visited[v] = true; // 标记起始顶点为已访问
        cout << G.vertices[v].data << " ";
        q.push(v); // 将起始顶点入队

        while (!q.empty()) {
                int u = q.front(); // 取出队列头部元素
                q.pop();
                ArcNode* p = G.vertices[u].firstarc; // 获取当前顶点的邻接点链表
                while (p != NULL) {
                        if (!visited[p->adjvex]) { // 如果邻接点未被访问
                                visited[p->adjvex] = true; // 标记为已访问
                                cout << G.vertices[p->adjvex].data << " ";
                                q.push(p->adjvex); // 将邻接点入队
                        }
                        p = p->nextarc; // 移动到下一个邻接点
                }
        }
}
void BFSTraverse(AlGraph G) {
        for (int i = 0; i < G.vexnum; i++) visited[i] = false; // 初始化
        for (int i = 0; i < G.vexnum; i++) {
                if (!visited[i]) { // 如果顶点未被访问
                        BFS(G, i); // 从该顶点开始进行 BFS
                        cout << endl; // 每个连通分量后换行
                }
        }
}
int main() {
        AlGraph G;
        if (CreateGraph(G)) {
                PrintfGraph(G);
                cout << "深度优先遍历结果:" << endl;
                DFSTraverse(G);
                cout << endl;
                cout << "广度优先遍历结果:" << endl;
                BFSTraverse(G);
        }
        else {
                printf("图创建失败!\n");
        }
        return 0;
}
    • 图的十字链表存储
#include<bits/stdc++.h>
using namespace std;
#define MAX_VEXTEX_NUM 20
typedef struct ArcBox{                        //弧结点
        int tailvex, headvex;
        struct ArcBox* hlink, * tlink;
        int weight;
}ArcBox;
typedef struct VexNode {                        //顶点结点
        char data;
        ArcBox* firstin, * firstout;
}VexNode;
typedef struct {
        VexNode xlist[MAX_VEXTEX_NUM];        //顶点表
        int vexnum, arcnum;                        //顶点数和弧数
}OLGraph;
int Locate(OLGraph G, char v) {
        for (int i = 0; i < G.vexnum; i++) {
                if (G.xlist[i].data == v) return i;        //返回顶点v在顶点表中的位置
        }
        return -1;
}
int CreateGraph(OLGraph& G) {
        cout << "请输入顶点数和弧数:";
        cin >> G.vexnum >> G.arcnum;

        cout << "请输入顶点信息:";
        for (int i = 0; i < G.vexnum; i++) {
                cin >> G.xlist[i].data;
                G.xlist[i].firstin = nullptr;
                G.xlist[i].firstout = nullptr;
        }

        cout << "请输入弧信息(起点 终点 权重):\n";
        for (int i = 0; i < G.arcnum; i++) {
                char v1, v2;
                int w;
                cin >> v1 >> v2 >> w;
                int p1 = Locate(G, v1), p2 = Locate(G, v2);
                if (p1 == -1 || p2 == -1) {
                        cout << "顶点不存在!\n";
                        return 0;
                }

                ArcBox* newArc = new ArcBox;
                newArc->headvex = p2;
                newArc->tailvex = p1;
                newArc->hlink = G.xlist[p2].firstin;
                newArc->tlink = G.xlist[p1].firstout;
                newArc->weight = w;

                G.xlist[p2].firstin = newArc;
                G.xlist[p1].firstout = newArc;
        }
}
void PrintGraph(OLGraph G) {
        cout << "图的顶点信息为:" << endl;
        for (int i = 0; i < G.vexnum; i++) {
                cout << G.xlist[i].data << " ";
        }
        cout << endl;

        cout << "图的边信息为:" << endl;
        for (int i = 0; i < G.vexnum; i++) {
                ArcBox* p = G.xlist[i].firstout;
                while (p != nullptr) {
                        cout << G.xlist[p->tailvex].data << " -> " << G.xlist[p->headvex].data << " (" << p->weight << ") ";
                        p = p->tlink;
                }
                cout << endl;
        }
}
int main() {
        OLGraph G;
        if (CreateGraph(G)) {
                PrintGraph(G);
        }
        else {
                cout << "图创建失败!\n";
        }
        return 0;
}
  • 图的临界多重表存储(省略)
  • 最小生成树
  •    普里姆算法(prim) 
    
#include <stdio.h>
#include <limits.h>

#define MAX_VERTEX_NUM 20
#define INF INT_MAX

typedef struct {
    int edges[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; // 邻接矩阵
    int numVertices; // 顶点数
    int minCost; // 最小生成树的总权重
} Graph;

// 查找最小边的顶点
int minKey(int key[], int mstSet[]) {
    int min = INF, min_index;
    for (int v = 0; v < MAX_VERTEX_NUM; v++) {
        if (mstSet[v] == 0 && key[v] < min) {
            min = key[v];
            min_index = v;
        }
    }
    return min_index;
}

// 打印生成的最小生成树
void printMST(int parent[], int graph[MAX_VERTEX_NUM][MAX_VERTEX_NUM], int numVertices) {
    printf("边 \t权重\n");
    for (int i = 1; i < numVertices; i++) {
        printf("%d - %d \t%d \n", parent[i], i, graph[i][parent[i]]);
    }
}

// 实现普利姆算法
void primMST(Graph* graph) {
    int parent[MAX_VERTEX_NUM]; // 存储最小生成树
    int key[MAX_VERTEX_NUM]; // 用于选择最小边的键值
    int mstSet[MAX_VERTEX_NUM]; // 表示顶点是否已经在最小生成树中

    // 初始化所有键值为无穷大,mstSet[] 为 false
    for (int i = 0; i < graph->numVertices; i++) {
        key[i] = INF;
        mstSet[i] = 0;
    }

    // 总是将第一个顶点作为最小生成树的根节点
    key[0] = 0;
    parent[0] = -1;

    for (int count = 0; count < graph->numVertices - 1; count++) {
        // 选择最小键值的顶点,该顶点未包含在 MST 中
        int u = minKey(key, mstSet);

        // 将选中的顶点添加到最小生成树中
        mstSet[u] = 1;

        // 更新相邻顶点的键值
        for (int v = 0; v < graph->numVertices; v++) {
            // 如果 v 在 MST 中,或者不存在从 u 到 v 的边,则不更新
            if (graph->edges[u][v] && mstSet[v] == 0 && graph->edges[u][v] < key[v]) {
                parent[v] = u;
                key[v] = graph->edges[u][v];
            }
        }
    }

    // 打印构造的最小生成树
    printMST(parent, graph->edges, graph->numVertices);
}

int main() {
    Graph graph;
    graph.numVertices = 5;

    // 邻接矩阵表示的图
    int graphEdges[5][5] = {
        {0, 2, 0, 6, 0},
        {2, 0, 3, 8, 5},
        {0, 3, 0, 0, 7},
        {6, 8, 0, 0, 9},
        {0, 5, 7, 9, 0}
    };
    graph.edges = graphEdges;

    // 调用普利姆算法
    primMST(&graph);

    return 0;
}
  •    克鲁斯卡尔算法(kruskal)
    
    #include <stdio.h>
#include <stdlib.h>

#define MAX_VERTEX_NUM 20
#define INF 999999

// 定义边的结构体
typedef struct {
    int begin;     // 边的起点
    int end;       // 边的终点
    int weight;    // 边的权重
} Edge;

// 定义子集的结构体,用于管理并查集
typedef struct {
    int parent[MAX_VERTEX_NUM]; // 存储每个元素的父节点
    int rank[MAX_VERTEX_NUM];   // 存储每个子集的秩
} Subset;

// 查找元素 i 所在的子集的根,并进行路径压缩
int find(Subset subsets, int i) {
    if (subsets.parent[i] != i) {
        subsets.parent[i] = find(subsets, subsets.parent[i]); // 路径压缩
    }
    return subsets.parent[i];
}

// 合并两个子集
int unionSets(Subset *subsets, int x, int y) {
    int xroot = find(*subsets, x);
    int yroot = find(*subsets, y);

    if (subsets->rank[xroot] < subsets->rank[yroot])
        subsets->parent[xroot] = yroot;
    else if (subsets->rank[xroot] > subsets->rank[yroot])
        subsets->parent[yroot] = xroot;
    else {
        subsets->parent[yroot] = xroot;
        subsets->rank[xroot]++;
    }
}

// 用于 qsort 的比较函数,按边的权重从小到大排序
int compareEdges(const void* a, const void* b) {
    Edge* a1 = (Edge*)a;
    Edge* b1 = (Edge*)b;
    return a1->weight - b1->weight;
}

// Kruskal算法实现
void KruskalMST(Edge edges[], int numEdges, int numVertices) {
    qsort(edges, numEdges, sizeof(Edge), compareEdges); // 对边按权重排序

    Subset subsets; // 初始化并查集
    for (int v = 0; v < numVertices; ++v) {
        subsets.parent[v] = v;
        subsets.rank[v] = 0;
    }

    Edge result[MAX_VERTEX_NUM]; // 存储最小生成树的边
    int e = 0; // 最小生成树的边数
    for (int i = 0; i < numEdges; ++i) {
        Edge next_edge = edges[i];
        int x = find(subsets, next_edge.begin);
        int y = find(subsets, next_edge.end);

        // 如果 x 和 y 不在同一个子集中,则将这条边加入到最小生成树中
        if (x != y) {
            result[e++] = next_edge;
            unionSets(&subsets, x, y);
        }
    }

    // 打印最小生成树的边和权重
    printf("边 \t权重\n");
    for (int i = 0; i < e; ++i) {
        printf("%d - %d \t%d \n", result[i].begin, result[i].end, result[i].weight);
    }
}

int main() {
    int numVertices = 4; // 顶点数
    int numEdges = 5;    // 边数
    Edge edges[MAX_VERTEX_NUM] = {
        {0, 1, 10}, // 边 0-1 权重 10
        {0, 2, 6},  // 边 0-2 权重 6
        {0, 3, 5},  // 边 0-3 权重 5
        {1, 3, 15}, // 边 1-3 权重 15
        {2, 3, 4}   // 边 2-3 权重 4
    };

    KruskalMST(edges, numEdges, numVertices); // 调用 Kruskal 算法

    return 0;
}

查找

  • 顺序查找和折半查找
#include<stdio.h>
#include<stdlib.h>
typedef struct{
        int* elem;
        int length;
}SSTable;

void init_SSTable(SSTable* ST, int n) {
        ST->elem = (int*)malloc((n + 1) * sizeof(int));
        if (ST->elem == NULL) {
                fprintf(stderr, "Memory allocation failed\n");
                exit(1);
        }
        ST->length = n;
        for (int i = 1; i <= n; i++) {
                scanf("%d", &ST->elem[i]);
        }
}
int Search_Seq(SSTable ST,int key) {                        //顺序查找
        for (int i = 1; i <= ST.length; i++) {
                if (ST.elem[i] == key) {
                        return i;
                }
        }
        return 0;
}

int Search_Seq2(SSTable ST, int key) {   //顺序查找,哨兵法
        ST.elem[0] = key;
        int i = ST.length;
        while (ST.elem[i] != key) {
                i--;
        }
        return i;
}

int Binary_Search(SSTable ST, int key) {                //折半查找
        if (ST.length == 0) return 0;
        int low = 1, right = ST.length;
        while (low <= right) {
                int mid = (low + right) / 2;
                if (ST.elem[mid] == key) return mid;
                else if (ST.elem[mid] < key) low = mid + 1;
                else right = mid - 1;
        }
        return 0;
}

int Binary_Search2(SSTable ST, int key) {        //折半查找,递归法
        if (ST.length == 0) return 0;
        int mid = ST.length / 2;
        if (ST.elem[mid] == key) return mid;
        else if (ST.elem[mid] < key) {
                SSTable ST2 = { ST.elem + mid + 1, ST.length - mid - 1 };
                return Binary_Search2(ST2, key);
        }
        else {
                SSTable ST2 = { ST.elem, mid };
                return Binary_Search2(ST2, key);
        }
}


int main() {

        return 0;
}
  • 分块查找
#include<stdio.h>
#include<stdlib.h>
typedef struct {
        int* data;
        int length;
}SSTable;

typedef struct {
        int* maxdata;  //块内的最大值
        int* index;                //起始位置
        int blocksize;                //块的大小
        int indexsize;        //索引表的大小
}BlockTable;                //索引表
int SSTabke_init(SSTable* sstable,int length) {
        sstable->length = length;
        sstable->data = (int*)malloc(sizeof(int) * length);
        if (sstable->data == NULL) {
                printf("data预分配内存失败");
                return -1;
        }
        return 0;
}
int BlockTable_init(BlockTable* blocktable, int blocksize, int indexsize) {
        blocktable->blocksize = blocksize;
        blocktable->indexsize = indexsize;
        blocktable->maxdata = (int*)malloc(sizeof(int) * indexsize);
        if (blocktable->maxdata == NULL) {
                printf("maxdata预分配内存失败\n");
                return -1;
        }
        blocktable->index = (int*)malloc(sizeof(int) * indexsize);
        if (blocktable->index == NULL) {
                printf("index预分配内存失败\n");
                return -1;
        }
        return 0;
}

//中间创建自己写

int Search_Block(SSTable* sstable, BlockTable* blocktable, int key) {
        int i = 0;
        for (; i < blocktable->indexsize && blocktable->maxdata[i] < key; i++); //找到第一个大于key的块
        if (i == blocktable->indexsize) {
                printf("没有找到\n");
                return -1;
        }
        int j = blocktable->index[i];
        for (; j < blocktable->index[i] + blocktable->blocksize; j++) {
                if (sstable->data[j] == key) {
                        return j; //找到key
                }
        }
}
int main() {

        return 0;
}
  • 哈希查找
#include <stdio.h>
#include <stdlib.h>
#define MAX_NUM 11

typedef struct {
    int* data;
    int length;
    int capacity;
} STable;

void Init(STable* T) {
    T->data = (int*)malloc(MAX_NUM * sizeof(int));
    if (T->data == NULL) {
        printf("内存分配失败\n");
        exit(-1);
    }
    T->length = 0;
    for (int i = 0; i < MAX_NUM; i++) {
        T->data[i] = -1; // 使用-1表示空
    }
    T->capacity = MAX_NUM;
}

int hash_function(int key) {
    return (key * 3) % 11;  // 简单的哈希函数
}
//线性探测再散列
int linearProbing(STable* T, int key) {
    if (T->length == MAX_NUM) {
        printf("哈希表已满,无法插入新元素\n");
        return -1;
    }
    int index = hash_function(key);
    while (T->data[index] != -1) {
        index = (index + 1) % MAX_NUM;
    }
    T->data[index] = key;  // 插入元素
    T->length++;  // 更新表的长度
    return index;
}
//二次探测再散列
int quadraticProbing(STable* T, int key) {
    if (T->length == MAX_NUM) {
        printf("哈希表已满,无法插入新元素\n");
        return -1;
    }
    int index = hash_function(key);
    int c = 0;
    while (T->data[index] != -1) {
        c++;
        // 尝试正负两个方向
        int plusIndex = (index + c * c) % MAX_NUM;
        int minusIndex = (index - c * c + MAX_NUM) % MAX_NUM; // 确保非负
        if (T->data[plusIndex] == -1) {
            index = plusIndex;
        }
        else if (T->data[minusIndex] == -1) {
            index = minusIndex;
        }
        else {
            // 如果正负方向都已占用,继续尝试下一个c值
            continue;
        }
    }
    T->data[index] = key;  // 插入元素
    T->length++;  // 更新表的长度
    return index;
}
//随机探测再散列
int randomProbing(STable* T, int key) {
    if (T->length == MAX_NUM) {
        printf("哈希表已满,无法插入新元素\n");
        return -1;
    }
    int index = hash_function(key);
    int attempts = 0;
    while (T->data[index] != -1) {
        index = (index + rand() % MAX_NUM) % MAX_NUM;
        attempts++;
        if (attempts == MAX_NUM) {
            printf("哈希表已满,无法插入新元素\n");
            return -1;
        }
    }
    T->data[index] = key;  // 插入元素
    T->length++;  // 更新表的长度
    return index;
}
int Hash_Search(STable* T, int key) {
    int index = hash_function(key);
    int start = index;
    int i = 0;
    while (T->data[index] != -1) {
        if (T->data[index] == key)
            return index;
        index = (index + 1) % MAX_NUM;
        if (index == start) { // 防止无限循环
            break;
        }
    }
    return -1;
}
void printHashTable(STable* T) {
    printf("哈希表内容:\n");
    for (int i = 0; i < MAX_NUM; i++) {
        if (T->data[i] == -1) {
            printf("哈希表[%d] = 空\n", i);
        }
        else {
            printf("哈希表[%d] = %d\n", i, T->data[i]);
        }
    }
}


int main() {
    STable T;
    Init(&T);

    int keys[] = { 22, 41, 53, 46, 30, 13, 1, 67 };
    int n = sizeof(keys) / sizeof(keys[0]);

    for (int i = 0; i < n; i++) {
        linearProbing(&T, keys[i]);
    }
        printHashTable(&T);

    int searchKey;
        printf("请输入要查找的元素: ");
        scanf_s("%d", &searchKey);
    int index = Hash_Search(&T, searchKey);

    if (index != -1) {
        printf("元素 %d 在哈希表中的位置是 %d\n", searchKey, index);
    }
    else {
        printf("哈希表中不存在元素 %d\n", searchKey);
    }

    // 释放内存
    free(T.data);

    return 0;
}

排序

  • 插入类
#include<stdio.h>
#include<stdlib.h>
typedef struct {
        int* data;
        int length;
        int capacity;
}STable;
void InitSTable(STable* st, int capacity) {
        st->data = (int*)malloc(capacity * sizeof(int));
        st->length = 0;
        st->capacity = capacity;
}
void CreateSTable(STable* st, int n) {
        if (n > st->capacity) {
                printf("Error: n exceeds capacity\n");
                return;
        }
        st->length = n;
        for (int i = 1; i <= n; i++) {
                scanf_s("%d", &st->data[i]);
        }
}
void PrintSTable(STable* st) {
        for (int i = 1; i <= st->length; i++) {
                printf("%d ", st->data[i]);
        }
        printf("\n");
}
void InsertSort(STable& st) {                //直接插入排序
        for (int i = 2; i <= st.length; i++) {
                if (st.data[i] < st.data[i - 1]) {
                        st.data[0] = st.data[i];
                        int j = i - 1;
                        while (j > 0 && st.data[j] > st.data[0]) {
                                st.data[j + 1] = st.data[j];
                                j--;
                        }
                        st.data[j + 1] = st.data[0];
                }
        }
}
void BInsertSort(STable& st) {         //折半插入排序
        for (int i = 2; i <= st.length; i++) {
                st.data[0] = st.data[i];
                int low = 1, high = i - 1, mid;
                while (low < high) {
                        mid = (low + high) / 2;
                        if (st.data[mid] > st.data[0]) {
                                high = mid - 1;
                        }
                        else {
                                low = mid + 1;
                        }
                }
                for (int j = i - 1; j >= low; j--)
                        st.data[j + 1] = st.data[j];
                st.data[low] = st.data[0];
        }
}
void ShellInsert(STable& st, int dk) {                //希尔排序
        for (int i = dk + 1; i <= st.length; i++) {
                if (st.data[i] < st.data[i - dk]) {
                        st.data[0] = st.data[i];
                        int j;
                        for (j = i - dk; j > 0 && st.data[j] > st.data[0]; j -= dk) {
                                st.data[j + dk] = st.data[j];
                        }
                        st.data[j + dk] = st.data[0];
                }
        }
}
void ShellSort(STable& st, int dlta[],int t) {
        for (int k = 0; k < t; k++)
                ShellInsert(st, dlta[k]);
}
void TestInsertSort() {
        STable st;
        InitSTable(&st, 10);
        CreateSTable(&st, 5); // 输入5个整数 5 3 4 6 2

        printf("InsertSort前: ");
        PrintSTable(&st); // 应输出 5 3 4 6 2

        InsertSort(st);
        printf("InsertSort后: ");
        PrintSTable(&st); // 应输出 2 3 4 5 6
}

void TestShellSort() {
        STable st;
        InitSTable(&st, 10);
        CreateSTable(&st, 9); // 输入9个整数 5 3 4 6 2 8 7 1 9

        printf("Before ShellSort: ");
        PrintSTable(&st); // 应输出 5 3 4 6 2 8 7 1 9
        int dlta[] = { 5, 3, 1 }; // 增量序列
        ShellSort(st, dlta, 3);

        printf("After ShellSort: ");
        PrintSTable(&st); // 应输出 1 2 3 4 5 6 7 8 9
}
int main() {
        TestInsertSort();
        TestShellSort();
        return 0;
}
  • 交换类
#include<stdio.h>
#include<stdlib.h>
typedef struct {
        int* data;
        int length;
        int capacity;
}STable;
void InitSTable(STable* st, int capacity) {
        st->data = (int*)malloc(capacity * sizeof(int));
        st->length = 0;
        st->capacity = capacity;
}
void CreateSTable(STable* st, int n) {
        if (n > st->capacity) {
                printf("Error: n exceeds capacity\n");
                return;
        }
        st->length = n;
        for (int i = 1; i <= n; i++) {
                scanf_s("%d", &st->data[i]);
        }
}
void PrintSTable(STable* st) {
        for (int i = 1; i <= st->length; i++) {
                printf("%d ", st->data[i]);
        }
        printf("\n");
}
void BubbleSort(STable& st) {                        //冒泡排序
        bool exchange;
        for (int i = 1; i <= st.length; i++) {
                exchange = false;
                for (int j = st.length; j > i; j--) {
                        if (st.data[j] < st.data[j-1]) {
                                st.data[0] = st.data[j - 1];
                                st.data[j - 1] = st.data[j];
                                st.data[j] = st.data[0];
                                exchange = true;
                        }
                }
                if (!exchange) break;
        }
}
int Partition(STable& st,int s,int t) {                //进行一次划分(快速排序)
        int low = s, high = t;
        st.data[0] = st.data[low];
        while (low < high) {
                while (low < high && st.data[high] >= st.data[0]) {
                        high--;
                }
                st.data[low] = st.data[high];
                while (low < high && st.data[low] <= st.data[0]) {
                        low++;
                }
                st.data[high] = st.data[low];
        }
        st.data[low] = st.data[0];
        return low;
}
void QuickSort(STable& st,int s,int t) {
        if (s < t) {
                int pivotloc = Partition(st, s, t);
                QuickSort(st, s, pivotloc - 1);  // 对左半部分递归排序
                QuickSort(st, pivotloc + 1, t);  // 对右半部分递归排序
        }
}
void TestBubbleSort() {
        STable st;
        InitSTable(&st, 10);
        CreateSTable(&st, 5);  // 输入 5 3 4 6 2(假设 data[0] 是哨兵)

        printf("Before BubbleSort: ");
        PrintSTable(&st);  // 输出 5 3 4 6 2

        BubbleSort(st);
        printf("After BubbleSort: ");
        PrintSTable(&st);  // 应输出 2 3 4 5 6

}
void TestQuickSort() {
        STable st;
        InitSTable(&st, 10);
        CreateSTable(&st, 8);  // 输入 4 6 1 3 8 2 5 9

        printf("Before QuickSort: ");
        PrintSTable(&st);  // 输出 4 6 1 3 8 2 5 9

        QuickSort(st, 1, st.length);  // 对 data[1..length] 排序
        printf("After QuickSort: ");
        PrintSTable(&st);  // 应输出 1 2 3 4 5 6 8 9

}
int main() {
        TestBubbleSort();
        TestQuickSort();
        return 0;
}
  • 选择类
#include<stdio.h>
#include<stdlib.h>
typedef struct {
        int* data;
        int length;
        int capacity;
}STable;
void InitSTable(STable* st, int capacity) {
        st->data = (int*)malloc(capacity * sizeof(int));
        st->length = 0;
        st->capacity = capacity;
}
void CreateSTable(STable* st, int n) {
        if (n > st->capacity) {
                printf("Error: n exceeds capacity\n");
                return;
        }
        st->length = n;
        for (int i = 1; i <= n; i++) {
                scanf_s("%d", &st->data[i]);
        }
}
void PrintSTable(STable* st) {
        for (int i = 1; i <= st->length; i++) {
                printf("%d ", st->data[i]);
        }
        printf("\n");
}
void SelectSort(STable& st) {                //简单选择排序
        for (int i = 1; i < st.length; i++) {
                int k = i;
                for (int j = i + 1; j <= st.length; j++)
                        if (st.data[j] < st.data[k])
                                k = j;
                if (k != i) {
                        st.data[0] = st.data[i];
                        st.data[i] = st.data[k];
                        st.data[k] = st.data[0];
                 }
        }

}
void HeapAdjust(STable& st, int s, int m) {                        //以大顶堆为例
        int rc = st.data[s];
        for (int j = 2 * s; j <= m; j*=2) {
                if (j < m && st.data[j] < st.data[j + 1])
                        j++;
                if (rc >= st.data[j]) break;
                        
                st.data[s] = st.data[j];
                s = j;
        }
        st.data[s] = rc;                //将rc放到合适的位置
}
void HeapSort(STable& st) {                //堆排序
        //建立初始堆
        for (int i = st.length / 2; i >= 1; i--)
                HeapAdjust(st, i, st.length);

        for (int i = st.length; i > 1; i--) {
                // 交换堆顶和堆底元素
                st.data[0] = st.data[1];
                st.data[1] = st.data[i];
                st.data[i] = st.data[0];

                // 调整堆
                HeapAdjust(st, 1, i - 1);
        }
}

void TestSelectSort() {
        STable st;
        InitSTable(&st, 10);
        CreateSTable(&st, 5);  // 输入 5 3 4 6 2(假设 data[0] 是哨兵)

        printf("Before SelectSort: ");
        PrintSTable(&st);  // 输出 5 3 4 6 2

        SelectSort(st);

        printf("After SelectSort: ");
        PrintSTable(&st);  // 应输出 2 3 4 5 6
}
void TestHeapSort() {
        STable st;
        InitSTable(&st, 10);
        CreateSTable(&st, 5);  // 输入 5 3 4 6 2(假设 data[0] 是哨兵)

        printf("Before sorting: ");
        PrintSTable(&st);  // 输出 5 3 4 6 2

        HeapSort(st);

        printf("After sorting: ");
        PrintSTable(&st);  // 应输出 2 3 4 5 6
}
int main() {
        TestSelectSort();
        TestHeapSort();
        return 0;
}
  • 归并类
#include <stdio.h>
#include <stdlib.h>

typedef struct {
    int* data;
    int length;
    int capacity;
} STable;

void InitSTable(STable* st, int capacity) {
    st->data = (int*)malloc((capacity + 1) * sizeof(int)); // 多分配一个空间给哨兵
    st->length = 0;
    st->capacity = capacity;
}

void CreateSTable(STable* st, int n) {
    if (n > st->capacity) {
        printf("Error: n exceeds capacity\n");
        return;
    }
    st->length = n;
    for (int i = 1; i <= n; i++) { // 从data[1]开始存储数据
        scanf_s("%d", &st->data[i]);
    }
}

void PrintSTable(STable* st) {
    for (int i = 1; i <= st->length; i++) {
        printf("%d ", st->data[i]);
    }
    printf("\n");
}

void Merge(STable* sr, STable* tr, int i, int m, int n) {
    int k, j;
    for (j = m + 1, k = i; i <= m && j <= n; k++) {
        if (sr->data[i] <= sr->data[j])
            tr->data[k] = sr->data[i++];
        else
            tr->data[k] = sr->data[j++];
    }
    while (i <= m)
        tr->data[k++] = sr->data[i++];
    while (j <= n)
        tr->data[k++] = sr->data[j++];
}

void MergeSort(STable* sr, STable* tr, int s, int t) {
    if (s < t) {
        int m = (s + t) / 2;
        MergeSort(sr, tr, s, m);      // 排序左半部分
        MergeSort(sr, tr, m + 1, t);  // 排序右半部分
        Merge(sr, tr, s, m, t);       // 合并两个有序子序列

        // 将结果复制回原数组(原地排序)
        for (int k = s; k <= t; k++) {
            sr->data[k] = tr->data[k];
        }
    }
}

void TestMergeSort() {
    STable sr, tr;
    InitSTable(&sr, 10);
    InitSTable(&tr, 10);

    printf("Input 5 numbers: ");
    CreateSTable(&sr, 5);  // 输入示例:5 3 4 6 2

    printf("Before sorting: ");
    PrintSTable(&sr);  // 输出:5 3 4 6 2

    tr.length = sr.length;
    for (int i = 1; i <= tr.length; i++) {
        tr.data[i] = 0;
    }

    MergeSort(&sr, &tr, 1, sr.length); // 从1开始排序

    printf("After sorting: ");
    PrintSTable(&sr);  // 正确输出:2 3 4 5 6

    free(sr.data);
    free(tr.data);
}

int main() {
    TestMergeSort();
    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2394537.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Centos环境下安装/重装MySQL完整教程

目录 一、卸载残留的MySQL环境&#xff1a; 二、安装MySQL&#xff1a; 1、下载MySQL官方的yum源&#xff1a; 2、更新系统yum源&#xff1a; 3、确保系统中有了对应的MySQL安装包&#xff1a; 4、安装MySQL服务&#xff1a; 5、密钥问题安装失败解决方法&#xff1a; …

【Linux】环境变量完全解析

9.环境变量 文章目录 9.环境变量一、命令行参数二、获取环境变量程序中获取环境变量1. 使用命令行参数2. 使用系统调用函数getenv("字符串");3. 使用系统提供的全局变量environ 命令行中查询环境变量 三、常见环境变量1. HOME2. OLDPWD3. PATH4. SHELL 四、环境变量与…

力扣每日一题——找到离给定两个节点最近的节点

目录 题目链接&#xff1a;2359. 找到离给定两个节点最近的节点 - 力扣&#xff08;LeetCode&#xff09; 题目描述 解法一&#xff1a;双指针路径交汇法​ 基本思路 关键步骤 为什么这样可行呢我请问了&#xff1f; 举个例子 特殊情况 Java写法&#xff1a; C写法&a…

卷积神经网络(CNN)入门学习笔记

什么是 CNN&#xff1f; CNN&#xff0c;全称 卷积神经网络&#xff08;Convolutional Neural Network&#xff09;&#xff0c;是一种专门用来处理图片、语音、文本等结构化数据的神经网络。 它模仿人眼识别图像的方式&#xff1a; 从局部到整体&#xff0c;一步步提取特征&a…

VLAN的作用和原理

1. 为什么要有vlan&#xff1f; 分割广播域&#xff0c;避免广播风暴&#xff0c;造成网络资源的浪费 可以灵活的组网&#xff0c;便于管理&#xff0c;同时还有安全加固的功能 2. vlan是怎么实现的&#xff1f;端口的原理&#xff1f; 设置VLAN后&#xff0c;流量之间的转…

深入探讨集合与数组转换方法

目录 1、Arrays.asList() 1.1、方法作用 1.2、内部实现 1.3、修改元素的影响 1.4、注意事项 2、list.toArray() 2.1、方法作用 2.2、内部实现 2.3、修改元素的影响 2.4、特殊情况 1、对象引用 2、数组copy 3、对比总结 4、常见误区与解决方案 5、实际应用建议…

【HarmonyOS 5应用架构详解】深入理解应用程序包与多Module设计机制

⭐本期内容&#xff1a;【HarmonyOS 5应用架构详解】深入理解应用程序包与多Module设计机制 &#x1f3c6;系列专栏&#xff1a;鸿蒙HarmonyOS&#xff1a;探索未来智能生态新纪元 文章目录 前言应用与应用程序包应用程序的基本概念应用程序包的类型标识机制应用安装流程 应用的…

【Oracle】DCL语言

个人主页&#xff1a;Guiat 归属专栏&#xff1a;Oracle 文章目录 1. DCL概述1.1 什么是DCL&#xff1f;1.2 DCL的核心功能 2. 用户管理2.1 创建用户2.2 修改用户2.3 删除用户2.4 用户信息查询 3. 权限管理3.1 系统权限3.1.1 授予系统权限3.1.2 撤销系统权限 3.2 对象权限3.2.1…

MySQL强化关键_017_索引

目 录 一、概述 二、索引 1.主键索引 2.唯一索引 3.查看索引 4.添加索引 &#xff08;1&#xff09;建表时添加 &#xff08;2&#xff09;建表后添加 5.删除索引 三、树 1.二叉树 2.红黑树 3.B树 4.B树 &#xff08;1&#xff09;为什么 MySQL 选择B树作为索引…

【备忘】php命令行异步执行超长时间任务

环境说明&#xff1a; 操作系统&#xff1a;windows10 IDE&#xff1a;phpstorm 开发语言&#xff1a;php7.4 框架&#xff1a;thinkphp5.1 测试环境&#xff1a;linuxwindows均测试通过。 初级方法&#xff1a; function longRunningTask() {$root_path Tools::get_ro…

在 RK3588 上通过 VSCode 远程开发配置指南

在 RK3588 上通过 VSCode 远程开发配置指南 RK3588 设备本身不具备可视化编程环境&#xff0c;但可以通过 VSCode 的 Remote - SSH 插件 实现远程代码编写与调试。以下是完整的配置流程。 一、连接 RK3588 1. 安装 Debian 系统 先在 RK3588 上安装 Debian 操作系统。 2. 安…

OpenHarmony标准系统-HDF框架之音频驱动开发

文章目录 引言OpenHarmony音频概述OpenHarmony音频框图HDF音频驱动框架概述HDF音频驱动框图HDF音频驱动框架分析之音频设备驱动HDF音频驱动框架分析之supportlibs实现HDF音频驱动框架分析之hdi-passthrough实现HDF音频驱动框架分析之hdi-bindev实现HDF音频驱动加载过程HDF音频驱…

HTML Day03

Day03 0. 引言1. CSS1.1 CSS的3种使用方法1.2 内联样式1.3 内部样式表1.4 外部CSS文件 2. 图像3. 表格3.1单元格间距和单元格边框 4. 列表4.1 有序表格的不同类型4.2 不同类型的无序表格4.3 嵌套列表 5. 区块6. 布局6.1 div布局6.2 表格布局 0. 引言 HELLO ^ _ ^大家好&#xf…

篇章六 数据结构——链表(二)

目录 1. LinkedList的模拟实现 1.1 双向链表结构图​编辑 1.2 三个简单方法的实现 1.3 头插法 1.4 尾插法 1.5 中间插入 1.6 删除 key 1.7 删除所有key 1.8 clear 2.LinkedList的使用 2.1 什么是LinkedList 5.2 LinkedList的使用 1.LinkedList的构造 2. LinkedList的…

吴恩达MCP课程(3):mcp_chatbot

原课程代码是用Anthropic写的&#xff0c;下面代码是用OpenAI改写的&#xff0c;模型则用阿里巴巴的模型做测试 .env 文件为&#xff1a; OPENAI_API_KEYsk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx OPENAI_API_BASEhttps://dashscope.aliyuncs.com/compatible-mode…

【清晰教程】查看和修改Git配置情况

目录 查看安装版本 查看特定配置 查看全局配置 查看本地仓库配置 设置或修改配置 查看安装版本 打开命令行工具&#xff0c;通过version命令检查Git版本号。 git --version 如果显示出 Git 的版本号&#xff0c;说明 Git 已经成功安装。 查看特定配置 如果想要查看特定…

JAVA 常用 API 正则表达式

1 正则表达式作用 作用一&#xff1a;校验字符串是否满足规则作用二&#xff1a;在一段文本中查找满足要求的内容 2 正则表达式规则 2.1 字符类 package com.bjpowernode.test14;public class RegexDemo1 {public static void main(String[] args) {//public boolean matche…

光电设计大赛智能车激光对抗方案分享:低成本高效备赛攻略

一、赛题核心难点与备赛痛点解析 全国大学生光电设计竞赛的 “智能车激光对抗” 赛题&#xff0c;要求参赛队伍设计具备激光对抗功能的智能小车&#xff0c;需实现光电避障、目标识别、轨迹规划及激光精准打击等核心功能。从历年参赛情况看&#xff0c;选手普遍面临三大挑战&a…

Python实现P-PSO优化算法优化BP神经网络回归模型项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档&#xff09;&#xff0c;如需数据代码文档可以直接到文章最后关注获取。 1.项目背景 在当今数据驱动的时代&#xff0c;回归分析作为预测和建模的重要工具&#xff0c;在科学研究和工业应用中占据着重要…

Microsoft的在word中选择文档中的所有表格进行字体和格式的调整时的解决方案

找到宏 创建 并粘贴 使用 Sub 全选所有表格() Dim t As Table an MsgBox("即将选择选区内所有表格&#xff0c;若无选区&#xff0c;则选择全文表格。", vbYesNo, "reboot提醒您!") If an - 6 Then Exit Sub Set rg IIf(Selection.Type wdSelectionIP, …