数据结构复习算法记录
一.线性表
1.顺序建链表
struct node* head, * p, * tail;int n;head = new node;//head = (struct node *)malloc(sizeof(struct node));head->next = NULL;tail = head;cin >> n;for (int i = 0; i < n; i++) {p = new node;cin >> p->data;p->next = NULL;tail->next = p;tail = p;}
2.逆序建链表
struct node* head, * p;int n;head = new node;head->next = NULL;cin >> n;for (int i = 0; i < n; i++) {p = new node;cin >> p->data;p->next = head->next;head->next = p;}
3.链表的逆置
struct node* reverse(struct node* head)
{struct node* p, * q;p = head->next;head->next = NULL;q = p->next;while (p != NULL){p->next = head->next;head->next = p;p = q;if (q != NULL)q = q->next;}return head;
}
4.有序链表的归并
struct node* Merge(struct node* head1, struct node* head2)
{struct node* p1, * p2, * tail;p1 = head1->next;p2 = head2->next;tail = head1;free(head2);while (p1 && p2){if (p1->data < p2->data){tail->next = p1;tail = p1;p1 = p1->next;}else{tail->next = p2;tail = p2;p2 = p2->next;}}if (p1)tail->next = p1;elsetail->next = p2;return head1;
}
5.删除链表中重复元素
struct node* Delete(struct node* head)
{struct node* p, * q, * t;p = head->next;while (p){q = p;t = q->next;while (t){if (t->data == p->data){q->next = t->next;t = q->next;}else{q = q->next;t = t->next;}}p = p->next;}return head;
}
6.双向链表
struct node
{int data;struct node *next;struct node *before;
};int main()
{struct node *head, *p, *tail;int n;head = (struct node *)malloc(sizeof(struct node));head->next = NULL;tail = head;cin >> n;while(n--){p = (struct node *)malloc(sizeof(struct node));cin >> p->data;p->next = NULL;tail->next = p;p->before = tail;tail = p;}return 0;
}
二.栈和队列
1.栈的实现
#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10
#define OVERFLOW -2
#define OK 1
#define ERROR 0typedef char SElemType;//栈结构体
typedef struct {SElemType *base;SElemType *top;int stacksize;
}SqStack;int InitStack(SqStack *S);//初始化栈
int Push(SqStack *S,SElemType e);//入栈
int Pop(SqStack *S,SElemType *e);//删除栈中的元素
int DestoryStack(SqStack *S);//销毁栈
int ClearStack(SqStack *S);//清空栈中的元素//初始化栈
int InitStack(SqStack *S) {S->base = (SElemType *)malloc(STACK_INIT_SIZE*sizeof(SElemType));if(!S->base) {exit(OVERFLOW);}S->top = S->base;S->stacksize = STACK_INIT_SIZE;return OK;
}//入栈
int Push(SqStack *S,SElemType e) {if((S->top-S->base)>=S->stacksize) {S->base = (SElemType*)realloc(S->base,(S->stacksize+STACKINCREMENT)*sizeof(SElemType));if(!S->base) {exit(OVERFLOW);}S->top = S->base + S->stacksize;S->stacksize += STACKINCREMENT;}*S->top++ = e;//printf("%c\n",e);return OK;
}//删除栈中的元素
int Pop(SqStack *S,SElemType *e) {if(S->top == S->base) return ERROR;*e = *--S->top;return OK;
}//清空栈中的元素
int ClearStack(SqStack *S) {S->top = S->base;return OK;
}//销毁栈
int DestoryStack(SqStack *S) {S->top = S->base;free(S->base);S->top = NULL;S->base = NULL;return OK;
}
三.串,数组,广义表
1.字符串模式匹配
给定主串s和模式串p,编写程序输出p在s中出现的首位置,若p不在s中则输出-1。字符串下标从0开始。
输入格式:
输入为2行,第1行主串s,第2行为模式串p。主串和模式串长度不超过100000。
输出格式:
输出为2行,第1行为若干整数,表示模式串p的失败函数值,每个整数后一个空格;第2行为一个整数,表示p在s中出现的首位置,若p不在s中则输出-1。
输入样例:
qwerabcabhlk
abcab
输出样例:
-1 -1 -1 0 1
4
#include<stdio.h>
#include<stdlib.h>
#include<string.h>int next[100009];void get_next(char *p, int lenp)
{//int* next = (int *)malloc(sizeof(int) * (lenp+1)); //lenp+1 注意数组越界访问int i = 0, j = -1;next[i] = j;while(i < lenp){if(j == -1 || p[j] == p[i]){i++;j++;next[i] = j;}else{j = next[j];}}
}int kmp(char* s, int lens, char *p, int lenp)
{if(lens < lenp)return -1;int i = 0, j = 0;while(i < lens && j < lenp){if(j == -1 || s[i] == p[j]){i++;j++;}else{j = next[j];}}return j == lenp ? i - j : -1;
}int main()
{char s[1000000], p[1000000];int n,i;scanf("%s",s);scanf("%s",p);int lens = strlen(s);int lenp = strlen(p);get_next(p, lenp);for(i = 1; i <= lenp; i++)printf("%d ",next[i]-1);printf("\n");int result = kmp(s, lens, p, lenp);printf("%d",result);return 0;
}
四.树和二叉树
1.二叉树基本操作(左右孩子表示法)
#include<bits/stdc++.h>
using namespace std;typedef struct TreeNode
{char data;struct TreeNode* lchild, * rchild;
}BTnode, * BinTree;BinTree creatTree() //先序创建二叉树
{char ch;BinTree BT;scanf("%c", &ch);if (ch == '#'){BT = NULL;}else{BT = (BinTree)malloc(sizeof(BTnode));BT->data = ch;BT->lchild = creatTree();BT->rchild = creatTree();}return BT;
}BinTree creatTree(char a[], char b[], int len) //先序和中序建树
{BinTree BT;int i;if (len == 0)return NULL;BT = (BinTree)malloc(sizeof(BTnode));BT->data = a[0];for (i = 0; i < len; i++){if (b[i] == a[0])break;}BT->lchild = creatTree(a + 1, b, i);BT->rchild = creatTree(a + 1 + i, b + i + 1, len - i - 1);return BT;
}BinTree creatTree(int a[], int b[], int len) //后序和中序建二叉树
{BinTree BT;int i;if (len == 0)return NULL;BT = (BinTree)malloc(sizeof(BTnode));BT->data = a[len - 1];for (i = 0; i < len; i++){if (b[i] == a[len - 1])break;}BT->lchild = creatTree(a, b, i);BT->rchild = creatTree(a + i, b + i + 1, len - i - 1);return BT;
}void InOrderTraverse(BinTree BT) //中序遍历
{if (BT){InOrderTraverse(BT->lchild);printf("%c", BT->data);InOrderTraverse(BT->rchild);}
}void BLtree(BinTree BT) //层序遍历,创建队列
{if (BT == NULL)return;int flag = 0;int front = -1, rear = 0;BinTree queue[50];queue[rear] = BT;while (front != rear){front++;if (flag++)printf(" ");printf("%d", queue[front]->data);if (queue[front]->lchild != NULL){rear++;queue[rear] = queue[front]->lchild;}if (queue[front]->rchild != NULL){rear++;queue[rear] = queue[front]->rchild;}}
}int getHeight(BinTree BT) //求树的高度
{int HL, HR, height;if (BT == NULL)return 0;HL = getHeight(BT->lchild);HR = getHeight(BT->rchild);height = (HL > HR ? HL : HR) + 1;return height;
}void changeLR(BinTree BT) //交换每个结点的左右孩子
{BinTree t;if (BT){t = BT->lchild;BT->lchild = BT->rchild;BT->rchild = t;changeLR(BT->lchild);changeLR(BT->rchild);}
}int main()
{int n;char a1[51], a2[51];scanf("%d", &n);scanf("%s %s", a1, a2);BinTree bt = creatTree(a1, a2, n);return 0;
}
2.完全二叉树的层序遍历(顺序存储)
一个二叉树,如果每一个层的结点数都达到最大值,则这个二叉树就是完全二叉树。
给定一棵完全二叉树的后序遍历,请你给出这棵树的层序遍历结果。
输入样例:
8
91 71 2 34 10 15 55 18
输出样例:
18 34 55 71 2 10 15 91
#include<stdio.h>
#include<stdlib.h>int n,tree[101];void creat(int i)
{if(i > n)return ;creat(2 * i);creat(2 * i + 1);scanf("%d",&tree[i]);
}int main()
{scanf("%d",&n);creat(1);for(int i = 1; i <= n; i++){if(i > 1)printf(" ");printf("%d",tree[i]);}return 0;
}
五.图论
1.图的遍历(DFS,BFS)
#include<bits/stdc++.h>
using namespace std;queue<int>q;
int G[11][11];
int vis[11] = { 0 };
int n, m; //点,边void DFS(int r)
{cout << r << " ";vis[r] = 1;for (int i = 0; i < n; i++) {if (vis[i] == 0 && G[r][i] == 1)DFS(i);}
}//DFS之后再BFS记得vis置0 —— memset(vis, 0, sizeof(vis));
void BFS(int r)
{if (vis[r] == 0)q.push(r);vis[r] = 1;for (int i = 0; i < n; i++) {if (vis[i] == 0 && G[r][i] == 1) {q.push(i);vis[i] = 1;}}while (!q.empty()) {int l = q.front();cout << l << " ";q.pop();BFS(l);}
}
2.最小生成树(访问图结点耗时最短,“扑克”算法)
(1)普里姆算法(Prim)
Prim算法_杨氏计算机知识整理-CSDN博客_prim算法
每次迭代选择相连的最小代价边的对应的点,加入到最小生成树中
#include<bits/stdc++.h>
using namespace std;#define MAX 100
#define MAXCOST 0x7fffffff int graph[MAX][MAX];int prim(int graph[][MAX], int n)
{int lowcost[MAX];int mst[MAX];int i, j, min, minid, sum = 0;for (i = 2; i <= n; i++){lowcost[i] = graph[1][i];mst[i] = 1; //mst[]存放MST外的点i到MST最短距离时候对应的MST里的点标号}mst[1] = 0;for (i = 2; i <= n; i++) //要找出n-1个点为止{min = MAXCOST;minid = 0;for (j = 2; j <= n; j++){if (lowcost[j] < min && lowcost[j] != 0){min = lowcost[j];minid = j;}}sum += min;lowcost[minid] = 0;for (j = 2; j <= n; j++){if (graph[minid][j] < lowcost[j])//不更新的话,lowcost[j]存的只是上一时刻的Lowcost[j],MST外部的点到minid的距离会不会比到之前的MST里点得最小距离小?{lowcost[j] = graph[minid][j];mst[j] = minid; //点j到MST内的lowcot对应的MST里的点事minid}}}return sum;
}
(2)克鲁斯卡尔算法(Kruskal)
选最小边加入生成树中
#include<bits/stdc++.h>
using namespace std;typedef struct Edge {int u, v;int cost;
}Edge;Edge edge[3002]; //边
int father[1002];
int n, m;bool cmp(Edge a, Edge b) //边,递增排序
{return a.cost < b.cost;
}int findFather(int x)
{if (father[x] == x)return x;return findFather(father[x]);
}int Kruskal()
{int sum = 0, cnt = 0;int fu, fv;for (int i = 0; i < m; i++){fu = findFather(edge[i].u);fv = findFather(edge[i].v);if (fu != fv) //同一父节点形成环则跳过{father[fu] = fv; //合并cnt++;sum += edge[i].cost;}}if (cnt == n - 1)return sum;elsereturn -1;
}int main()
{cin >> n >> m;for (int i = 0; i < m; i++){cin >> edge[i].u >> edge[i].v >> edge[i].cost;}sort(edge, edge + m, cmp);for (int i = 1; i <= n; i++) // 最初,每个顶点为一个独立集合 father[i] = i;int sum = Kruskal();cout << sum;
}
3.拓扑排序
(1)AOV网
数据结构与算法A实验六图论---7-5 任务调度的合理性(拓扑排序)_趟水过河的博客-CSDN博客
(2)AOE网
数据结构与算法A实验六图论---7-7 最短工期 (拓扑排序)_趟水过河的博客-CSDN博客
4.最短路径问题
(1)迪杰斯特拉算法(Dijkstra,从某个源点到其余各顶点的最短路径)
#include<bits/stdc++.h>
using namespace std;#define INF 0x3f3f3f3f
#define max 3000
int Map[max][max];
int dis[max];
bool vis[max] = { false };
int Min;
int n, m, s, t;void Dijkstra()
{dis[s] = 0;vis[s] = true;for (int i = 0; i < n; i++) { //每次求得起始点到某个v顶点的最短路径,并加到vis集Min = INF;for (int k = 1; k <= n; k++) {if (!vis[k] && dis[k] < Min) {Min = dis[k];s = k; //以下s已经改变}}vis[s] = true; //离起始点最近的点加入vis集for (int k = 1; k <= n; k++) { //更新当前最短路径及距离if (!vis[k] && Min + Map[k][s] < dis[k]) {dis[k] = Min + Map[k][s];}}}
}int main()
{int a, b, w;cin >> n >> m >> s >> t;for (int i = 1; i <= n; i++) {for (int j = 1; j <= n; j++) {Map[i][j] = INF;}}//memset(Map, INF, sizeof(Map));for (int i = 0; i < m; i++) {cin >> a >> b >> w;Map[a][b] = Map[b][a] = w;}for (int i = 1; i <= n; i++) {dis[i] = Map[i][s]; //Map[i][s]为点i到起始点的直接距离(i到s的弧)}Dijkstra();cout << dis[t] << endl;return 0;
}
(2)弗洛伊德算法(Floyd,每一对顶点之间的最短路径)
void Floyd()
{for (int k = 1; k <= n; k++) {for (int i = 1; i <= n; i++) {for (int j = 1; j <= n; j++) {if (i != j) //自己通向自己的路跳过 Map[i][j] = min(Map[i][k] + Map[k][j], Map[i][j]);}}}
}
六.查找
(1)线性表查找
(2)树表查找
平衡二叉树的调整:数据结构与算法基础(青岛大学-王卓)_哔哩哔哩_bilibili
(3)散列表查找(构造hash函数)
数据结构与算法基础(青岛大学-王卓)_哔哩哔哩_bilibili
七.排序
1.插入排序
(1).直接插入排序
i0为哨兵(和要插入的值相同),i1本身被当作有序,所以从i2开始取元素插入排序
(2)折半插入排序(二分法)
(3)希尔排序
分成若干子序列进行直接插入排序,最后进行全部进行插入排序
2.交换排序
(1).冒泡排序
#include<stdio.h>
int main()
{int n, a[100], i, j, t;scanf("%d", &n);for (i = 0; i < n; i++)scanf("%d", &a[i]);for (i = 0; i < n - 1; i++) {for (j = 0; j < n - 1 - i; j++) {if (a[j] > a[j + 1]) {t = a[j];a[j] = a[j + 1];a[j + 1] = t;}}}return 0;
}
(2).快速排序
void Quick_sort(int a[], int l, int r)
{int x = a[l], i = l, j = r;if (l >= r)return;while (i < j){while (i < j && a[j] >= x) j--;a[i] = a[j];while (i < j && a[i] <= x) i++;a[j] = a[i];}a[i] = x;Quick_sort(a, l, i - 1);Quick_sort(a, i + 1, r);
}
3.选择排序
(1)简单选择排序
每次选择最小的放在前面(打擂)
(2)堆排序
数据结构与算法基础(青岛大学-王卓)_哔哩哔哩_bilibili
堆调整
4.归并排序(适合外排序)
数据结构-浙江大学_哔哩哔哩_bilibili
5.基数排序(多关键字排序)
数据结构与算法基础(青岛大学-王卓)_哔哩哔哩_bilibili
数据结构复习算法记录相关推荐
- KPM算法——数据结构|复习局|串|复杂模式匹配算法|二维数组解决KPM
数据结构复习局--KPM算法 何为KPM? 事先规则 状态 匹配 dp--状态转移图 状态X 获得dp数组值 看看图再理解下 写在前面: 本文仅为作者个人学习记录,详细具体内容参考自知乎大佬labul ...
- CAUC算法与数据结构复习基本代码(一)
算法与数据结构复习基本代码(一) 线性表 线性表 顺序表 单链表 双链表 栈 栈 顺序栈 链式栈 表达式求值 队列 顺序队列 链式队列 字符串 线性表 线性表 线性表的抽象数据类型定义 templat ...
- CAUC数据结构与算法期末复习归纳(二)
CAUC数据结构与算法期末复习归纳(二) 二叉树 二叉树的周游 二叉树的抽象数据类型 深度优先周游二叉树或其子树 广度优先周游二叉树 二叉树的存储结构 二叉树的链式存储结构 二叉搜索树 二叉搜索树的性 ...
- 数据结构与算法复习(持续更新中)
目录 数组 为什么很多编程语言中数组都从0开始编号? 如何实现随机访问 数组和链表的区别 链表 栈 函数调用栈来保存临时变量,为什么函数调用要用"栈"来保存临时变量呢?用其他数据结 ...
- 为什么我要现在复习学习数据结构和算法
前言 最近人工智能,深度学习特别的火,做为一个软件开发者来说,我们应该对行业形势保持足够的敏感度,同时面对变化我们结合自身情况找准自己的学习方向. 我对人工智能有着极大的兴趣 说实话作为一个开 ...
- 数据结构与算法复习:一
算法复习第一天:论序 一.先了解几个人 ① 号目标人物 ② 号目标人物 二.数据结构的兴起和发展 1.客观世界与计算机世界的关系 2.程序设计的实质是什么 3.数据结构是随着程序设计的发展而发展的 三 ...
- 拿命 3 天肝出来的计算机考研数据结构与算法复习笔记(超详细教程,更新中)
数据结构与算法 基本概述 数据结构指的是"一组数据的存储结构",算法指的是"操作数据的一组方法". 数据结构是为算法服务的,算法是要作用再特定的数据结构上的. ...
- Ants (POJNo.1852)--数据结构与算法刷题记录
数据结构与算法刷题记录1 时间:4.28 这是第一次用CSDN来记录自己的学习成果,在此留下纪念,希望自己能够坚持下去,变得更强. 本次学习记录来源于<挑战程序设计竞赛(第2版)> Ant ...
- 【课程记录·本】WUT数据结构与算法综合实验 | 基于C++MFC的欢乐连连看游戏的设计与实现(附下载链接)
本文基于文章" https://blog.csdn.net/cxh_1231/article/details/89577820 "二次修改发布,原文已失效,不再维护 我的微信公众号 ...
最新文章
- ajax实现多选 radio true,jQuery操作radio、checkbox、select的方法总结
- Windows界面编程-背景图片、透明特效使用
- 关于Unity中NGUI的Pivot和锚点
- ArcGIS(A column was specified that does not exist)
- rewind java_Java LongBuffer rewind()用法及代码示例
- Linux四剑客详解——awk
- keil中编译时出现*** ERROR L107: ADDRESS SPACE OVERFLOW
- c语言数据结构和数据类型_C语言中的数据类型
- 海康 Isecure VMS 客户端二次开发简单记录
- Vue中变量前加...三个点什么意思
- 梅隆大学计算机专业申请,卡耐基梅隆大学计算机专业申请要求及研究方向
- 建立软件工程之动态模型(状态图)步骤
- 什么是云服务器ECS?云服务器是干什么的?
- nrf uart for android,nrf connect
- 中国地质大学英语语音学习笔记(四):英语连读——弱读、冠词连读方法(包括元音字母前添加an的原因)和词间辅音加元音的连读方法
- 论文阅读笔记:《自然语言处理中的预训练模型》
- ARIMA模型的拖尾截尾问题
- apollo自动驾驶进阶学习之:如何调试减速带通行限速参数
- Glusterfs|ceph实现分布式存储
- 视频号5种提高曝光量的技巧