搜索二叉树
#include <bits/stdc++.h>
using namespace std;struct TreeNode
{int val;TreeNode* left;TreeNode* right;TreeNode(int x) :val(x),left(nullptr),right(nullptr) {}
};// 搜索二叉树
// 每个节点的左子树中的所有节点值都小于该节点的值,而右子树中的所有节点值都大于该节点的值。
TreeNode* insert(TreeNode* root, int val) // 插入,递归函数 第一个参数是根节点
{if (root == nullptr){return new TreeNode(val);}if (val < root->val){root->left = insert(root->left, val);}else{root->right = insert(root->right, val);}return root;
}void preorder(TreeNode* root) // 前序遍历
{if (root == nullptr){return;}cout << root->val << " ";preorder(root->left);preorder(root->right);
}void inorder(TreeNode* root) // 中序遍历
{if (root == nullptr){return;}inorder(root->left);cout << root->val << " ";inorder(root->right);
}void postorder(TreeNode* root) // 后序遍历
{if (root == nullptr){return;}inorder(root->left);inorder(root->right);cout << root->val << " ";
}
int main()
{TreeNode* root = nullptr;root = insert(root, 4);insert(root, 2);insert(root, 6);insert(root, 1);insert(root, 3);insert(root, 5);insert(root, 7);// 先序遍历cout << "先序遍历: ";preorder(root);cout << endl;// 中序遍历cout << "中序遍历: ";inorder(root);cout << endl;// 后序遍历cout << "后序遍历: ";postorder(root);cout << endl;return 0;
}
栈
//栈 后进先出
#include <bits/stdc++.h>
using namespace std;class Stack {
private:vector<int> data;
public:Stack() {}void push(int val) // 入栈{data.push_back(val);}void pop() // 出栈{if (isEmpty()){cout << "wrong" << '\n';return;}data.pop_back();}int top() const {if (isEmpty()) {std::cout << "Stack is empty, no top element." << std::endl;return -1; // 返回一个错误值}return data.back();}bool isEmpty() const{return data.empty();}
};
int main()
{Stack s;s.push(10);s.push(20);s.push(30);cout << "Top element: " << s.top() << std::endl; s.pop();cout << "Top element after pop: " << s.top() << std::endl; return 0;
}
队列
//队列 先进先出
#include <bits/stdc++.h>
using namespace std;struct Node
{int data;Node* next;Node(int val) : data(val),next(nullptr) {}
};
class Queue {
private:Node* frontNode; // 记录头Node* rearNode; // 记录尾
public:Queue() : frontNode(nullptr),rearNode(nullptr) {}~Queue() {while (!isEmpty()){dequeue();}}void dequeue() {if (isEmpty()){cout << "wrong" << endl;return;}Node* temp = frontNode;frontNode = frontNode->next;delete temp;if (frontNode == nullptr) { // 边界处理rearNode = nullptr;}}bool isEmpty() const {return frontNode == nullptr;}int front() {if (isEmpty()){cout << "wrong" << endl;return -1;}return frontNode->data;}void enqueue(int val){Node* newNode = new Node(val);if (isEmpty()){frontNode = rearNode = newNode;}else{rearNode->next = newNode;rearNode = newNode;}}
};
int main()
{Queue q;q.enqueue(1);q.enqueue(2);q.enqueue(3);cout << q.front() << '\n';q.dequeue();cout << q.front() << '\n';return 0;
}
双向循环链表
#include <bits/stdc++.h>
using namespace std;
class Node
{
public:int data;Node* prev;Node* next;Node(int val) : data(val),prev(nullptr),next(nullptr){}
};
class DoubleList
{
private:Node* head;
public:DoubleList() : head(nullptr){}void append(int val) // 尾插{Node* newnode = new Node(val);if (!head) // 第一个元素特判{head = newnode;head->next = head;head->prev = head;}else{newnode->next = head;newnode->prev = head->prev;head->prev->next = newnode;head->prev = newnode; }}void deleteNode(int val) // 删除指定值(链表没下标){if (!head) // 一个元素都没有{return;}Node* current = head; // 从头节点开始遍历int flag = 0;do // 确保找过一遍{flag = 1;if (current->data != val){current = current->next;}else // 注意不只要删除一个{if (current->next == current) // 加上只有一个的特判{delete current;head = nullptr;return;}else{Node* prevNode = current->prev;Node* nextNode = current->next;prevNode->next = nextNode;nextNode->prev = prevNode;if (current == head) // 如果删除的是头节点,更新头节点{head = nextNode;flag = 0;}Node* temp = current;current = current->next;delete temp; }}}while (current != head || flag == 0);}Node* search(int val){if (!head){return nullptr;}Node* current = head;do {if (current->data == val) {return current;}current = current->next;} while (current != head);return nullptr;}int length() {if (!head) return 0;int len = 0;Node* current = head;do {len++;current = current->next;} while (current != head);return len;}void printList(){if (!head) return;Node* current = head;do {cout << current->data << " ";current = current->next;} while (current != head);cout << '\n';return;}
};
int main()
{DoubleList list;//初始化list.append(1);list.append(2);list.append(3);list.append(4);list.append(5);list.append(1);list.printList();list.deleteNode(1);list.printList();cout << list.length() << '\n';return 0;
}
顺序表
#define _CRT_SECURE_NO_WARNINGS//顺序表 静态和动态
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include "sep.h"struct seplist//静态
{int aa[100];int size;//有效数据个数
};struct dplist//动态 更常用
{int* a;int size;//有效数据个数;int capa;//顺序表当前大小
}sl;void begin(struct dplist* sl)//初始化
{sl->a = NULL;sl-> size = 0;sl-> capa = 0;
}
void sltest()//定义
{struct dplist sl;begin(&sl);
}
void destroy(struct dplist* sl) //销毁空间,不要浪费
{if (sl->a)free(sl->a);sl->a = NULL;sl->capa = 0;sl->size = 0;
}
void checkcapa(struct dplist* sl)//检查空间是否足够 不够的话自动扩容
{if (sl->size == sl->capa){int newcapa = sl->capa == 0 ? 4 : 2 * sl->capa;struct dplist* tmp = (struct dplist*)realloc(sl->a, newcapa * sizeof(struct dplist));if (tmp == NULL){perror("fall");return ;}sl->a = tmp;sl->capa = newcapa;//因为本来sl->capa为0,所以定义newcapa}
}
void pushback(struct dplist* sl,int x)//尾插
{//assert(sl)if (sl == NULL)//比assert柔和的方式{return;}//判断空间checkcapa(sl);//sl已经是指针了,直接传//插入数据 注意size的指向 要指向下一个,因为后面还要插sl->a[sl->size] = x;sl->size++;
}
void pushfront(struct dplist* sl,int x)//头插 历史数据后移
{if (sl == NULL){return;}//判断空间checkcapa(sl);//直接调用函数//后移历史数据for (int i = sl->size; i > 0; i--){sl->a[i] = sl->a[i - 1];}//头插sl->a[0] = x;sl->size++;
}
void popback(struct dplist* sl)//尾删
{if (sl == NULL){return;}//判断是否已经为空if (sl->size == 0){return;}sl->size--;//在size的数据如果下次size到这里就会覆盖掉
}
void popfront(struct dplist* sl)//头删 数据直接向左移动来覆盖
{if (sl == NULL){return;}//判断是否已经为空if (sl->size == 0){return;}//向左移动for (int i = 0; i < sl->size ; i++){sl->a[i] = sl->a[i + 1];}
}
void slinsert(struct dplist* sl, int pos, int x)//指定位置插入数据 pos为下标
{if (sl == NULL){return;}checkcapa(sl);//把pos及后面的数据向后挪for (int i = sl->size; i > pos; i--){sl->a[i] = sl->a[i - 1];}//对pos加以限制,避免程序崩溃if (pos < 0 || pos > sl->size){return;}//注意size的值 因为又插入了值sl->a[pos] = x;sl->size++;
}
void sldelete(struct dplist* sl, int pos)//指定位置删除数据 也是覆盖 往前移动
{//经典判断if (sl == NULL){return;}//判断是否已经为空if (sl->size == 0){return;}//对pos加以限制,避免程序崩溃if (pos < 0 || pos >= sl->size){return;}//往前覆盖for (int i = pos; i < sl->size - 1; i++){sl->a[i] = sl->a[i + 1];}sl->size--;//数据减少
}
int slfind(struct dplist* sl,int x)//查找数据是否存在 存在返回1 否则-1
{// 经典判断if (sl == NULL){return;}for (int i = 0; i < sl->size; i++){if (sl->a[i] == x){return 1;}}return -1;
}
void slprint(struct dplist* sl)//打印顺序表 看操作是否正确
{for (int i = 0; i < sl->size; i++){printf("%d ", sl->a[i]);}printf("\n");
}
int main()
{return 0;
}
插入完全二叉树的三种遍历
#include <bits/stdc++.h>
using namespace std;struct TreeNode
{int val;TreeNode* left;TreeNode* right;TreeNode(int x) :val(x),left(nullptr),right(nullptr) {}
};// 搜索二叉树
// 每个节点的左子树中的所有节点值都小于该节点的值,而右子树中的所有节点值都大于该节点的值。
TreeNode* insert(TreeNode* root, int val) // 插入,递归函数 第一个参数是根节点
{if (root == nullptr){return new TreeNode(val);}if (val < root->val){root->left = insert(root->left, val);}else{root->right = insert(root->right, val);}return root;
}void preorder(TreeNode* root) // 前序遍历
{if (root == nullptr){return;}cout << root->val << " ";preorder(root->left);preorder(root->right);
}void inorder(TreeNode* root) // 中序遍历
{if (root == nullptr){return;}inorder(root->left);cout << root->val << " ";inorder(root->right);
}void postorder(TreeNode* root) // 后序遍历
{if (root == nullptr){return;}inorder(root->left);inorder(root->right);cout << root->val << " ";
}
int main()
{TreeNode* root = nullptr;root = insert(root, 4);insert(root, 2);insert(root, 6);insert(root, 1);insert(root, 3);insert(root, 5);insert(root, 7);// 先序遍历cout << "先序遍历: ";preorder(root);cout << endl;// 中序遍历cout << "中序遍历: ";inorder(root);cout << endl;// 后序遍历cout << "后序遍历: ";postorder(root);cout << endl;return 0;
}
通过前序构建二叉树
赫夫曼编码及树综合 带权路径和
//#include <bits/stdc++.h>
//#include <unordered_map>
//using namespace std;
//
//struct treenode
//{
// int val;
// treenode* left;
// treenode* right;
// treenode(int x) : val(x), left(nullptr), right(nullptr) {}
//};构建二叉树
//treenode* buildTree(const string& preorder, int& index) {
// if (index >= preorder.size() || preorder[index] == '0') {
// index++;
// return nullptr;
// }
// treenode* root = new treenode(preorder[index++]);
// root->left = buildTree(preorder, index);
// root->right = buildTree(preorder, index);
// return root;
//}//int main()
//{
// int t;
// cin >> t;
// while (t--)
// {
// string str;
// cin >> str;
// int index = 0;
// treenode* root = buildTree(str, index);
// }
// return 0;
//}
计算带权路径和
赫夫曼编码及树综合 带权路径和
//#include <bits/stdc++.h>
//#include <unordered_map>
//using namespace std;
//
//struct treenode
//{
// int val;
// treenode* left;
// treenode* right;
// treenode(int x) : val(x), left(nullptr), right(nullptr) {}
//};
//先序遍历模板
//void pre(treenode* root, vector<int>& result)
//{
// if (root == nullptr) return;
// result.push_back(root->val);
// pre(root->left, result);
// pre(root->right, result);
//}
//中序遍历模板
//void in(treenode* root, vector<int>& result) {
// if (root == nullptr) return;
// in(root->left, result);
// result.push_back(root->val);
// in(root->right, result);
//}
//后序遍历模板
//void post(treenode* root, vector<int>& result) {
// if (root == nullptr) return;
// post(root->left, result);
// post(root->right, result);
// result.push_back(root->val);
//}
//构建二叉树
//treenode* buildTree(const string& preorder, int& index) {
// if (index >= preorder.size() || preorder[index] == '0') {
// index++;
// return nullptr;
// }
// treenode* root = new treenode(preorder[index++]);
// root->left = buildTree(preorder, index);
// root->right = buildTree(preorder, index);
// return root;
//}
//计算带权路径和
//int calculatew(treenode* root, unordered_map<char, int>& weights, int depth)
//{
// if (root == nullptr) return 0;
// if (root->left == nullptr && root->right == nullptr) {
// return weights[root->val] * depth;
// }
// return calculatew(root->left, weights, depth + 1) + calculatew(root->right, weights, depth + 1);
//}
//
//
//int main()
//{
// int t;
// cin >> t;
// while (t--)
// {
// string str;
// cin >> str;
// int index = 0;
// treenode* root = buildTree(str, index);
// int n;
// cin >> n;
// unordered_map<char, int> weights;
// for (int i = 0; i < n; i++)
// {
// char leaf;
// int weight;
// cin >> leaf >> weight;
// weights[leaf] = weight;
// }
// int wpl = calculatew(root, weights, 0);
// cout << wpl << endl;
// }
// return 0;
//}
计算二叉树最大路径
赫夫曼编码及树综合 二叉树之最大路径
//#include <bits/stdc++.h>
//#include <unordered_map>
//using namespace std;
//
//struct treenode
//{
// int val;
// treenode* left;
// treenode* right;
// treenode(int x) : val(x), left(nullptr), right(nullptr) {}
//};
//先序遍历模板
//void pre(treenode* root, vector<int>& result)
//{
// if (root == nullptr) return;
// result.push_back(root->val);
// pre(root->left, result);
// pre(root->right, result);
//}
//中序遍历模板
//void in(treenode* root, vector<int>& result) {
// if (root == nullptr) return;
// in(root->left, result);
// result.push_back(root->val);
// in(root->right, result);
//}
//后序遍历模板
//void post(treenode* root, vector<int>& result) {
// if (root == nullptr) return;
// post(root->left, result);
// post(root->right, result);
// result.push_back(root->val);
//}
//构建二叉树
//treenode* buildTree(const string& preorder, int& index) {
// if (index >= preorder.size() || preorder[index] == '0') {
// index++;
// return nullptr;
// }
// treenode* root = new treenode(preorder[index++]);
// root->left = buildTree(preorder, index);
// root->right = buildTree(preorder, index);
// return root;
//}
//计算最大路径权值
//int maxPathSum(TreeNode* root) {
// if (root == nullptr) return 0;
// if (root->left == nullptr && root->right == nullptr) return root->weight;
// int leftSum = maxPathSum(root->left);
// int rightSum = maxPathSum(root->right);
// return root->weight + max(leftSum, rightSum);
//}
//
//int main() {
// int t;
// cin >> t;
// while (t--) {
// string preorder;
// cin >> preorder;
// int index = 0;
//
// int n;
// cin >> n;
// vector<int> weights(n);
// for (int i = 0; i < n; ++i) {
// cin >> weights[i];
// }
//
// int weightIndex = 0;
// TreeNode* root = buildTree(preorder, index, weights, weightIndex);
// int maxSum = maxPathSum(root);
// cout << maxSum << endl;
// }
//
// return 0;
//}
通过中后序遍历求二叉树以及求叶子节点最小值
// 二叉树的中后序遍历构建及求叶子
#include <iostream>
#include <vector>
#include <string>
#include <unordered_map>
#include <algorithm>
#include <climits>using namespace std;struct TreeNode {int val;TreeNode* left;TreeNode* right;TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};// 构建二叉树
TreeNode* buildTreeHelper(const vector<int>& inorder, int inStart, int inEnd,const vector<int>& postorder, int postStart, int postEnd,unordered_map<int, int>& inMap) {if (inStart > inEnd || postStart > postEnd) return nullptr;int rootVal = postorder[postEnd];TreeNode* root = new TreeNode(rootVal);int inRoot = inMap[rootVal];int numsLeft = inRoot - inStart;root->left = buildTreeHelper(inorder, inStart, inRoot - 1,postorder, postStart, postStart + numsLeft - 1, inMap);root->right = buildTreeHelper(inorder, inRoot + 1, inEnd,postorder, postStart + numsLeft, postEnd - 1, inMap);return root;
}TreeNode* buildTree(const vector<int>& inorder, const vector<int>& postorder) {unordered_map<int, int> inMap;for (int i = 0; i < inorder.size(); ++i) {inMap[inorder[i]] = i;}return buildTreeHelper(inorder, 0, inorder.size() - 1,postorder, 0, postorder.size() - 1, inMap);
}// 查找叶子节点权值的最小值
void findMinLeaf(TreeNode* root, int& minLeaf) {if (root == nullptr) return;if (root->left == nullptr && root->right == nullptr) {minLeaf = min(minLeaf, root->val);}findMinLeaf(root->left, minLeaf);findMinLeaf(root->right, minLeaf);
}int main() {int N;while (cin >> N) {vector<int> inorder(N);vector<int> postorder(N);for (int i = 0; i < N; ++i) {cin >> inorder[i];}for (int i = 0; i < N; ++i) {cin >> postorder[i];}TreeNode* root = buildTree(inorder, postorder);int minLeaf = INT_MAX;findMinLeaf(root, minLeaf);cout << minLeaf << endl;}return 0;
}
取有无向图的类型、顶点和边的信息,构建邻接矩阵,并计算每个顶点的度信息,最后输出邻接矩阵、度信息和孤立顶点
图的存储及遍历// 巧妙邻接表
#include <bits/stdc++.h>
#include <unordered_map>
#include <map>
#include <iostream>
#include <vector>
#include <unordered_map>using namespace std;int main() {int T;cin >> T;while (T--) {char graphType;int vertexCount;cin >> graphType >> vertexCount;vector<char> vertices(vertexCount);unordered_map<char, int> vertexIndex;for (int i = 0; i < vertexCount; ++i) {cin >> vertices[i];vertexIndex[vertices[i]] = i;}int edgeCount;cin >> edgeCount;vector<vector<int>> adjMatrix(vertexCount, vector<int>(vertexCount, 0));for (int i = 0; i < edgeCount; ++i) {char u, v;cin >> u >> v;int uIndex = vertexIndex[u];int vIndex = vertexIndex[v];adjMatrix[uIndex][vIndex] = 1;if (graphType == 'U') {adjMatrix[vIndex][uIndex] = 1;}}// 输出邻接矩阵cout << "Adjacency Matrix:" << endl;for (int i = 0; i < vertexCount; ++i) {for (int j = 0; j < vertexCount; ++j) {cout << adjMatrix[i][j] << " ";}cout << endl;}// 计算度信息vector<int> inDegree(vertexCount, 0);vector<int> outDegree(vertexCount, 0);vector<int> degree(vertexCount, 0);for (int i = 0; i < vertexCount; ++i) {for (int j = 0; j < vertexCount; ++j) {if (adjMatrix[i][j] == 1) {outDegree[i]++;inDegree[j]++;degree[i]++;if (graphType == 'U') {degree[j]++;}}}}// 输出度信息cout << "Degrees:" << endl;for (int i = 0; i < vertexCount; ++i) {if (graphType == 'D') {if (outDegree[i] > 0 || inDegree[i] > 0) {cout << vertices[i] << ": " << outDegree[i] << " " << inDegree[i] << " " << degree[i] << endl;}}else {if (degree[i] > 0) {cout << vertices[i] << ": " << degree[i] << endl;}}}// 输出孤立点bool hasIsolated = false;for (int i = 0; i < vertexCount; ++i) {if (degree[i] == 0) {if (!hasIsolated) {cout << "Isolated vertices:" << endl;hasIsolated = true;}cout << vertices[i] << " ";}}if (hasIsolated) {cout << endl;}}return 0;
}
bfs例子
//dfs和bfs两道题的例子 1.bfs
#include <bits/stdc++.h>
#include <unordered_map>
#include <map>
#include <vector>using namespace std;void bfs(const vector<vector<int>>& adjMatrix, int start, vector<bool>& visited, vector<int>& result)
{queue<int> q;q.push(start);while (!q.empty()){int v = q.front();q.pop();result.push_back(v);for (int i = 0; i < adjMatrix.size(); ++i){if (adjMatrix[v][i] == i && !visited[i]){q.push(i);visited[i] = true;}}}
}
void solve()
{int n;cin >> n;vector<vector<int>> adjMatrix(n, vector<int>(n));for (int i = 0; i < n; ++i) {for (int j = 0; j < n; ++j) {cin >> adjMatrix[i][j];}}vector<bool> visited(n, false);vector<int> result;bfs(adjMatrix, 0, visited, result);for (int i = 0; i < result.size(); ++i) {if (i > 0) cout << " ";cout << result[i];}
}
int main()
{int t;cin >> t;while(t--){solve();}return 0;
}
dfs例子
//dfs和bfs两道题的例子 2.dfs
#include <bits/stdc++.h>
#include <unordered_map>
#include <map>
#include <vector>using namespace std;void dfs(const vector<vector<int>>& adjMatrix, int v, vector<bool>& visited, vector<int>& result)
{visited[v] = true;result.push_back(v);for (int i = 0; i < adjMatrix.size(); ++i){if (adjMatrix[v][i] == 1 && !!visited[i]){dfs(adjMatrix, i, visited, result);}}
}
void solve()
{int n;cin >> n;vector<vector<int>> adjMatrix(n, vector<int>(n));for (int i = 0; i < n; ++i){for (int j = 0; j < n; ++j){cin >> adjMatrix[i][j];}}vector<bool> visited(n, false);vector<int> result;dfs(adjMatrix, 0, visited, result);for (int i = 0; i < result.size(); ++i) {if (i > 0) cout << " ";cout << result[i];}
}
int main()
{int t;cin >> t;while (t--){solve();}return 0;
}