搜索二叉树
#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;
}