当前位置: 首页 > news >正文

数据结构-代码总结

下面代码自己上完课写着玩的,除了克鲁斯卡尔那里完全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个位置插入元素valueif (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) {                                //删除表中的所有valueif (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); // 初始容量为5cout << "初始化线性表,容量为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);                                //由于函数需要添加了tempcase '@':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里面的NULLint 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) {                //copyint 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.hif (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和firstchildfirstchild表示该点的第一个孩子结点,孩子结点用链表的方式存储
*/
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); // 从该顶点开始进行 BFScout << 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_MAXtypedef 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[] 为 falsefor (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 11typedef 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 2printf("InsertSort前: ");PrintSTable(&st); // 应输出 5 3 4 6 2InsertSort(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 9printf("Before ShellSort: ");PrintSTable(&st); // 应输出 5 3 4 6 2 8 7 1 9int 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 2BubbleSort(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 9printf("Before QuickSort: ");PrintSTable(&st);  // 输出 4 6 1 3 8 2 5 9QuickSort(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 2SelectSort(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 2HeapSort(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++];elsetr->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 2printf("Before sorting: ");PrintSTable(&sr);  // 输出:5 3 4 6 2tr.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 6free(sr.data);free(tr.data);
}int main() {TestMergeSort();return 0;
}

相关文章:

  • golang 柯里化(Currying)
  • 嵌入式开发学习(第二阶段 C语言笔记)
  • Golang | gRPC索引服务
  • Java jdk8版本特性(未完成版)
  • 截图后怎么快速粘贴到notability?
  • 常规算法学习
  • 打印Yolo预训练模型的所有类别及对应的id
  • 基于Unsloth框架快速微调Qwen3-14B模型的全面指南,包括Unsloth框架技术原理与微调代码实现
  • jenkins报错java.lang.OutOfMemoryError: Java heap space
  • 基于bp神经网络的adp算法
  • 创建型设计模式之Singleton(单例)设计模式
  • SMME 2025:创新海洋工程模式,迎接未来挑战
  • Android Compose开发架构选择指南:单Activity vs 多Activity
  • 银河麒麟V10通过制作rpm包升级httpd、php软件修复漏洞
  • Python 训练营打卡 Day 38
  • 浅谈国企数字化转型
  • Jenkins-Pipeline:学习笔记
  • 什么是软件的生命周期,以及常见的开发测试模型
  • 电脑软件管家 免安装便携 四十多种功能系统优化”“磁盘清理”“隐私保护
  • 【行动指南】大一如何高效备考java
  • 网站建设服务中心/上海优化外包
  • 重庆江北网站建设/ttkefu在线客服系统官网
  • 聊城网站建设项目/腾讯营销平台
  • 网站建设维护单位/seo关键词的优化技巧
  • 郑州个人做网站/西地那非片能延时多久每次吃多少
  • 网站维护 上海/关键词优化app