1.链表
- 在带头结点的链表中,删除所有值为x的结点
void Del_X(Linklist &L,ElemType x){
LNode *p=L->next, *pre=L,*q;
while (p!=null){
if (p->data==x){
q=p;
p=p->next;
pre->next=p;
free(q);
}
else{
pre=p;
p=p->next;
}
}
}
- 使用单链表进行插入排序
ListNode* insertSort(ListNode *head){
ListNode *dummy = new ListNode(0),*cur = head;
while (cur){
ListNode *pre = dummy,*next = cur->next;
//找到第一个比cur大的元素
while (pre->next && pre->next->val<=cur->val)
pre = pre->next;
cur->next = pre->next;
pre->next = cur;
cur = next;
}
return dummy->next;
}
- 使用单链表进行简单选择排序
void SelectSort(LinkList L){
LinkList p,q,min;
DataType temp;
p = L->next;
while (p!=null){
min = p;
q = p->next;
while (q!=null){
if (q->data<min->data)
min = q;
q = q->next;
}
if (p->data>min->data){
temp = p->data;
p->data = min->data;
min->data = temp;
}
p = p->next;
}
}
- 判断单链表是否有环
int hasLoop(Node *head){
Node *p1,*p2;
if (head==null || head->next==null){ //链表为空,或者是单节点链表
return 0;
}
p1=p2=head;
while (p1->next!=null && p2->next->next!=null){
p1 = p1->next;
p2 = p2->next->next;
if (p1==p2)
return 1;
}
return 0;
}
2. 二叉树
- 使用递归算法在一颗二叉搜索树上插入一个元素
BSTNode* insertIntoBST(TreeNode *root,Element e){
int k = e.key;
if (!root){ //root为空
BSTNode *p = (BSTNode *)malloc(sizeof(BSTNode));
p->lchild = null;
p->rchild = null;
p->val = k;
return p;
}
if (k>root->val){ //插入到右子树
root->rchild = insertIntoBST(root->rchild,e);
}
else if (k<root->val){ //插入到左子树
root->lchild = insertIntoBST(root->lchild,e);
}
return root;
}
- 已知满二叉树先序序列,求二叉树的后序序列
void PreToPost(ElemType* pre, int l1, int h1, ElemType* post, int l2, int h2)
{
int half;
if(h1>=l1){
post[h2]=pre[l1]; //先序的第一个变为后序的最后一个
half=(h1-l1)/2;
//递归调用
PreToPost(pre,l1+1,l1+half,post,l2,l2+half-1);
PreToPost(pre,l1+half+1,h1,post,l2+half,h2-1);
}
}
- 判断一棵树是否为完全二叉树
//空结点使用NULL来表示
bool is_complete_bt(TreeNode* root){
queue<TreeNode*> q;
q.push(root);
while(!q.empty()){
TreeNode* node=q.front();
q.pop();
if(node==null)
break;
else{
q.push(node->left);
q.push(node->right);
}
}
while(!q.empty()){
TreeNode* node=q.front();
q.pop();
if(node!=null)
return false;
}
return true;
}
- 给你二叉树的根节点
root
和一个整数目标和targetSum
,找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。
vector<vector<int>> lists;
vector<vector<int>> pathSum(TreeNode* root, int targetSum) {
if (root==nullptr)
return lists;
vector<int> list;
dfs(root,targetSum,list);
return lists;
}
void dfs(TreeNode* root, int targetSum,vector<int> list){
if (root==nullptr)
return;
list.push_back(root->val);
if (root->val==targetSum && root->left==nullptr && root->right==nullptr)
lists.push_back(list);
dfs(root->left,targetSum-root->val,list);
dfs(root->right,targetSum-root->val,list);
list.pop_back();
}
- 合并二叉排序树
void BSTree_Merge(BiTree &T,BiTree &S){
if (S->lchild){
BSTree_Merge(T,S->lchild);
}
if (S->rchild){
BSTree_Merge(T,S->rchild);
}
Insert_Node(T,S);
}
void Insert_Node(BSTree &T, BSTree *S){
if (S->data > T->data){
if (!T->right) //T的右子树为空
T->right = S;
else{
Insert_Node(T->right,S);
}
}
else if (S->data < T->data){
if (!T->left)
T->left = S;
else{
Insert_Node(T->left,S);
}
}
S->left = null;
S->right = null; //插入的新结点和原来的左右子树断绝关系
}
- 验证二叉搜索树
long long pre = LONG_MIN;
bool isValidBST(TreeNode* root) {
if (root == nullptr)
return true;
if (!isValidBST(root->left))
return false;
if (root->val <= pre)
return false;
pre = root->val;
return isValidBST(root->right);
}
- 删除二叉搜索树中的最大值
bool DelMax(BSTree &T){
BSTNode *p = T,*q=p;
if (!p) //树为空
return false;
while (p->rchild){ //找到最右端的结点
q=p;
p=p->rchild;
}
if (p==T) //无右子树
T=T->lchild;
else
q->rchild = p->lchild;
return true;
}
- 输出AVL搜索树中所有结点的平衡因子
int depth(BTree root){
if (root==null)
return 0;
int l = depth(roo->left);
int r = depth(root->right);
return (l>r?l:r)+1;
}
void print_num(BTree root){
if (root!=null){
printf("结点%d的平衡因子为%d\n",root->val,depth(root->left) - depth(root->right));
print_num(root->left);
print_num(root->right);
}
}
3. 图
- 图的深度优先遍历
void DFS(Graph G,int k){ //对结点k进行深度优先遍历
visit(k); //访问k
visited[k]; //标记为已访问
//邻接矩阵
for (int i=0;i<G->n;i++) //结点k所对应的那一行
if (D->Edges[k][i]==1 && visited[i]==false)
DFS(G,i);
//邻接表
ENode *p;
for (p = G->adjList[k]->firstarc;p;p = p->nextarc){
int temp = p->adjvex;
if (!visited[temp])
dfs(G,temp);
}
}
时间复杂度 O(|V|^2) 空间复杂度O(|V|)
图的深度优先遍历(非递归)
void DFS(Graph G,int v){
InitStack(S); //初始化一个栈
for (int i=0;i<G.vexnum;i++)
visited[i] = false;
Push(S,v);
visited[v] = true;
while (!isEmpty(S)){
k = Pop(S);
visit(k);
for (int p = G.adjlist[v].firstarc;p; p=p->nextarc){
if (!visited[p]){
Push(S,p);
visited[p]=true;
}
}
}
}
- 判断无向图顶点 i 和 j 是否存在长度为k的路径
int visited[MAXSIZE];
int dfs(Graph G,int i,int j,int k){
if (i==j && k==0)
return 1;
ENode *p;
if (k>0){
visited[i]=1;
//p.vertices[i] 邻接表的顶点
for (p=G.adjList[i].firstarc;p;p=p->nextarc){
//边表的第一个结点
int temp = p->adjvex;
if (!visited[temp] && dfs(G,temp,j,k-1))
return 1;
}
visited[i]=0;
}
return 0;
}
- 输出图中顶点 i 到顶点 j 的所有路径
void dfs(Graph graph, int v, int end, bool visit[], int path[], int cnt)
{
visit[v] = true;
path[cnt++] = v;
if(v == end)
{
for(int i = 0; i < cnt; i++)
{
cout<<path[i]<<" ";
}
cout<<endl;
return;
}
for(ENode* p = graph.adjList[v].firstarc; p ; p=p->next)
{
if(!visit[p->adjvex])
{
dfs(graph, p->adjvex, end, visit, path, cnt);
}
//回溯
visit[p->adjvex] = false;
}
}
- 求用邻接表存储的无向图中“节点总数恰好为k”的连通分量数量 (邻接表的题,弄懂这一个就够了)
bool visited[MAXSIZE];
int concomx(Graph G){
int count = 0;
int vnum = 0;
for (int i=0;i<G.vexnum;i++){
visited[i] = false;
}
for (int i=0;i<G.vexnum;i++){
vnum = 0;
if (visited[i] == false){
dfs(G,i,visited,vnum);
}
if (vnum==k)
count++;
}
return count;
}
void dfs(Graph G,int v,bool visited,int vnum){
ENode *p;
visited[v] = true;
vnum++;
for (p=G->adjList[i]->firstarc;p;p=p->nextarc){
int temp = p->adjvex;
if (visited[temp]==false){
dfs(G,temp,visited,vnum);
}
}
}
- 判断 图是否可以转化为一颗树
图是连通的且无环
bool isTree(Graph &G){
for(int i=1;i<=G.vexnum;i++){
visited[i]=FALSE;
}
int Vnum=0,Enum=0;
DFS(G,1,Vnum,Enum,visited);
//一次遍历,顶点数等于图的顶点数,边数等于2*(n-1),说明可以转化为一棵树
if(Vnum==G.vexnum&&Enum==2*(G.vexnum-1)){ //无向图,边数应为结点数-1的2倍
return true;
}
else return false;
}
void DFS(Graph &G,int v,int& Vnum,int& Enum,bool visted[]){
ENode *p;
visited[v]=TRUE;
Vnum++;
for (p = G->adjList[i]->firstarc;p;p = p->nextarc){
Enum++;
if (!visited[p->adjvex]){
DFS(G,p->adjvex,Vnum,Enum,visited);
}
}
}
- 无向图采用邻接表的方式存储,删除边(i,j)
void DeleteArc(Graph G,int i,int j){
//删除其中一条边 i到j
ENode *pre = null;
ENode *p = G->adjList[i].firstarc; //结点i的第一个相邻结点
while (p){
if (p->adjvex==j){
if (pre==null){
G->adjList[i]->firstarc = p->nextarc;
}
else
pre->nextarc = p->nextarc;
free(p);
}
else{
pre = p;
p = p->next;
}
}
//删除另一条边 j到i
ENode *qpre = null;
ENode *q = G->adjList[j].firstarc;
while (q){
if (q->adjvex==i){
if (qpre==null){
adjList[j].firstarc = q->nextarc;
}
else
pre->nextarc = q->nextarc;
free(q);
}
else{
qpre = q;
q = q->next;
}
}
}
- 有向无环图,找出能访问图中所有节点的最小点集
思路:找出入度为零的节点即可
vector<int> findSmallestSetOfVertices(int n, vector<vector<int>>& edges) {
vector<int> ans;
vector<int> inDegree(n);
for (auto &info : edges){
inDegree[info[1]]++;
}
for (int i=0;i<n;i++){
if (inDegree[i]==0)
ans.push_back(i);
}
return ans;
}
- 求邻接表表示的图的出度和入度
void Degree(int* degree,Graph *G){
int i;
ENode *p;
for (i=0;i<G->n;i++)
degree[i] = 0;
for (i=0;i<G->n;i++){
for (p = G->adjList[i]->firstarc;p;p = p->nextArc){
degree[i]++; //求出度
ingree[p->adjvex]++; //求入度
}
}
}
4. 其他
- 使用递归求数组中n个数的平均值
int avg(int a[],int n){
if (n>0)
return (a[n-1]+avg(a,n-1)*(n-1))/n;
return 0;
}
- 递归求幂集(全排列)
示例
输入: nums = [1,2,3]
输出:
[
[3],
[1],
[2],
[1,2,3],
[1,3],
[2,3],
[1,2],
[]
]
vector<int> t;
vector<vector<int>> ans;
void dfs(int cur, vector<int>& nums) {
ans.push_back(t);
for (int i = cur;i<nums.size();i++){
t.push_back(nums[i]);
dfs(i+1,nums);
t.pop_back();
}
}
vector<vector<int>> subsets(vector<int>& nums) {
dfs(0, nums);
return ans;
}
- 对一个排序去重(有重复的关键字,删除前一个,保留后一个)
void Delete(SqList &L){
for (int i = 1;i<L.length;i++){
int j = i-1;
if (L.data[i]==L.data[j]){
for (int k=j;k<L.length;k++)
L.data[k] = L.data[k+1];
L.length--;
}
}
}
- 从有序顺序表中删除所有值重复的元素,使表中的值均不相同
bool delete_all(SqList &L) {
int i;
int k=0;//k记录重复元素个数
for(i=1;i<L.Length;i++){
if(L.data[i-1]==L.data[i]){
k++;
}
L.data[i-k]=L.data[i];
}
L.Length=L.Length-k;
return true;
}
- 队列和栈
Stack S;
Top(S,x); 获取栈顶元素并够通过x返回
Push(S,x);
Pop(S);
Queue Q;
Front(Q,x);
EnQueue(Q,x);
DeQueue(Q);
- 快速排序
int Partition(ElemType A[],int low,int high){
ElemType pivot = A[low];
while (low<high){
while (low<high && A[high]>=pivot)
high--;
while (low<high && A[low]<=pivot)
low++;
}
A[low] = pivot; //枢轴元素存放到最终位置
return low;
}
void QuickSort(ElemType A[],int low,int high){
if (low<high){
int pivot = Partition(A,low,high);
QuickSort(A,low,pivot-1);
QuickSort(A,pivot+1,high);
}
}