数据结构经典算法集锦

第2章 线性表

  1. KMP算法
//获得next数组
void GetNext(char *t, int next[MAX])
{int i = 1, j = 0;next[1] = 0//设t[0]中为字符串长度, 字符保存在t[1]之后while(i < t[0]){if(j == 0 || t[i] == t[j]){i++; j++; next[i] = j;}else{j = next[j];}}
}
//next[i]=j表示在t[1...i-1]中,最长公共前后缀长度为j-1
//KMP(假设已经使用过GetNext)
void KMP_index(char *s, char *t, int next[MAX])
{int i = 1, j = 1;while(i <= s[0] && j <= t[0]){if(j == 0 || s[i] == t[j]){i++; j++;}else{j = next[j];}}if(j > t[0])return i - t[0];elsereturn -1; //没有匹配成功
}
  1. 单向环形链表反向
//设原来的环形链表为a1->a2->a3->a4->a1
//Reverse后的环形链表为a4->a3->a2->a1->a4
void Reverse(LIST &R)
{position p, q;p = R->next;R->next = p->next;p->next = p;while(p->next != R){q = R->next;R->next = q->next;q->next = p->next;p->next = q;}R = p;
}

第3章 树

  1. 二叉树三种遍历非递归实现
//数据结构定义
typedef struct T{struct T* lchild;ElemType data;struct T* rchild;
}BiTree;//先序遍历非递归
void NPreOrder(BiTree* root)
{BiTree* stack[MAX];int top = 0;do{while(root != NULL){visit(root->data);top++;if(top >= MAX){cout << "栈满!" << endl;exit();}else{stack[top] = root;}root = root->lchild;}if(top != 0){root = stack[top--];root = root->rchild;}}while(root != NULL || top != 0);
}//中序遍历非递归实现
void NInOrder(BiTree* root)
{BiTree* stack[MAX];int top = 0;do{while(root != NULL){top++;if(top >= MAX){cout << "栈满!" << endl;exit();}else{stack[top] = root;}root = root->lchild;}if(top != 0){root = stack[top--];visit(root->data);root = root->rchild;}}while(root != NULL || top != 0);
}//后序遍历非递归实现
void NPostOrder(BiTree* root)
{BiTree* stack[MAX];int top = 0;BiTree* p = NULL;int b;do{while(root != NULL){top++;if(top >= MAX){cout << "栈满!" << endl;exit();}else{stack[top] = root;}root = root->lchild;}b = 1; //b标记是否处于回退状态p = NULL;while(top != 0 && b){root = stack[top];if(root->rchild == p){visit(root->data);p = root; //p指向刚刚访问过的结点top--;}else{root = root->rchild;b = 0; //遍历右子树,不再处于回退状态}}}
}
  1. 线索二叉树
//数据结构定义
typedef struct node{struct node* lchild;struct node* rchild;bool ltag;bool rtag;ElemType data;
}ThTree;
//若左子树为空,则p->ltag=false, 且p->lchild=$p(p的中序前导结点)
//若左子树不空,则p->ltag=true, 且p->lchild=左子树的根
//若右子树为空,则p->rtag=false, 且p->rchild=p$(p的中序后继结点)
//若右子树不空,则p->rtag=true, 且p->rchild=右子树的根//将二叉树中序线索化
ThTree* pre = NULL; //全局变量,保存中序前驱
void InOrderTh(ThTree* p)
{//中序线索化本质上也是一个中序遍历的过程if(p){InOrderTh(p->lchild);p->ltag = p->lchild ? true : false;p->rtag = p->rchild ? true : false;if(pre){if(p->ltag == false)p->lchild = pre;if(pre->rtag == false)pre->rchild = p;}pre = p;InOrderTh(p->rchild);}}//利用线索二叉树求某一结点的中序后继
ThTree* InNext(ThTree* p)
{ThTree* q = p->rchild;if(p->rtag == true){while(q->ltag == true)q = q->lchild;}return q;
}
//利用线索二叉树进行非递归中序遍历
void ThInOrder(ThTree* HEAD)
{ThTree* tmp = HEAD;do{tmp = InNext(tmp);if(tmp != HEAD)visit(tmp->data);}while(tmp != HEAD);
}
//数据结构定义
typedef struct{int key;/*other fields*/
}ElemType;typedef struct H{ElemType elements[MAX];int n; //堆中元素的个数
}Heap;//向(最大)堆中插入一个元素,并保持堆的状态(整理堆)
void Insert(Heap &heap, ElemType item)
{int i;if(!HeapFull(heap)){i = ++heap.n;while((i != 1) && item > heap.elements[i/2]){heap.elements[i] = heap.elements[i/2];i /= 2;}heap.elements[i] = item;   }
}//删除(最大)堆的根结点中元素
void DeleteMax(Heap &heap)
{int parent = 1, child = 2;ElemType item, tmp;if(!HeapEmpty(heap)){item = heap.elements[1];tmp = heap.elements[heap.n--];while(child <= heap.n){if(child+1 <= heap.n && heap.elements[child] < heap.elements[child+1]){child++;}if(heap.elements[child] > tmp){heap.elements[parent] = heap.elements[child];parent = child;child = parent*2;}elsebreak;}heap.elements[parent] = tmp;return item;}
}
  1. 哈夫曼树
//数据结构定义
typedef struct H{double weight;int lchild;int rchild;int parend; //parent=-1表示没有父结点
}HuffmanT[MAX];//辅助函数:从一个线性序列中选出两个最小元素
void SelectMin(HuffmanT T, int n, int &p1, int &p2)
{int i, j, k;for(i = 0; i < n; i++){if(T[i].parent == -1) {p1 = i; break;}}for(j = i+1; j < n; j++){if(T[j].parent == -1) {p2 = j; break;}}for(i = 0; i < n; i++){if(T[i].parent == -1 && T[i].weight < T[p1].weight && i != p2)p1 = i;}for(j = 0; j < n; j++){if(T[j].parent == -1 && T[j].weight < T[p2].weight && j != p1)p2 = j;}
}
//构造哈夫曼树
void CreateHT(Huffman &T)
{int i, p1, p2;InitHT(T); //初始化,输入权重for(i = n; i <= m; i++){SelectMin(T, i-1, p1, p2);//将p1和p2合并到iT[i].lchild = p1;T[i].rchild = p2;T[i].weight = T[p1].weight + T[p2].weight;T[p1].parent = T[p2].parent = i;}
}

第4章 图

  1. Prim算法求最小生成树
//用邻接矩阵保存图
const int n = 100;
void Prim(costtype C[n+1][n+1]) //C为权重矩阵,没有边就设为inf
{int CLOSEST[n+1]; //保存V-U中的点与U中点的最小权costtype LOWCOST[n+1]; //保存V-U中的点与U中哪个点是最小权int i, j, k;costtype min;//初始化U只包含1for(i = 2; i <= n; i++){CLOSEST[i] = 1;LOWCOST[i] = C[1][i];}for(i = 2; i <= n; i++){//从V-U中选取LOWCOST最小的点k = i; min = LOWCOST[i];for(j = 2; j <= n; j++){if(LOWCOST[j] < min){k = j; min = LOWCOST[j];}}//输出树边cout << "(" << k << "," << CLOSEST[k] << ")"  << endl;LOWCOST[k] = inf; //将k加入U//更新LOWCOST和CLOSESTfor(j = 2; j <= n; j++){if(LOWCOST[j] != inf && LOWCOST[j] > C[k][j]){LOWCOST[j] = C[k][j];CLOSEST[j] = k;}}}
}
  1. Kruskal算法求最小生成树
//数据结构定义
//Kruskal算法要求从边的角度逼近最小生成树
typedef struct{int begin;int end;costtype cost;
}EdgeSet[MAX];//Kruskal
void Kruskal(EdgeSet edges, int n, int e) //n为顶点数,e为边数
{int i, bnf, edf;MFSET parents;for(i = 1; i <= n; i++){initial(i, parents);}Sort(edges); //将边集按权不减的排序for(i = 1; i <= e; i++){bnf = Find(parents, edges[i].begin);edf = Find(parents, edges[i].end);if(bnf != edf){cout << edges[i].begin << " " << edges[i].end << " " << edges[i].cost << endl;Union(parents, bnf, edf);}}
}
  1. Dijistra算法求单源最短路径
//输入权重矩阵,设源点为1
void Dijistra(costtype C[n+1][n+1], costtype D[n+1], int P[n+1])
{int i, j, k;int S[n+1];costtype min;for(i = 1; i <= n; i++){S[i] = 0; D[i] = C[1][i]; P[i] = 1;}//初始时S只包含1S[1] = 1;for(i = 2; i <= n; i++){//从S外找一点D[i]最小的点for(j = 2; j <= n; j++){if(S[j] == 0)break;}k = j;min = D[j];for(j = k+1; j <= n; j++){if(S[j] == 0 && D[j] < min){min = D[j];k = j;}}S[k] = 1;//更新D和Pfor(j = 2; j <= n; j++){if(S[j] == 0 && D[j] > D[k] + C[k][j]){D[j] = D[k] + C[k][j];P[j] = k;}}}
}//找路径
void FindPath(int P[MAX], int u)
{if(P[u] != 1){FindPath(P, P[u]);cout << P[u] << endl;}
}
  1. Floyd算法求任意两点间最短路径
//
void Floyd(costtype C[n+1][n+1], costtype D[n+1][n+1], int P[n+1][n+1])
{int i, j, k;for(i = 1; i <= n; i++){for(j = 1; j <= n; j++){D[i][j] = C[i][j];P[i][j] = 0;}}for(k = 1; k <= n; k++){for(i = 1; i <= n; i++){for(j = 1; j <= n; j++){if(D[i][j] > D[i][k] + D[k][j]){D[i][j] = D[i][k] + D[k][j];P[i][j] = k;}}}}
}//找路
void FindPath(int P[n+1][n+1], int u, int v)
{if(u != v){FindPath(P, u, P[u][v]);cout << P[u][v] << endl;FindPath(P, P[u][v], v);}
}
  1. 拓扑排序算法
//输入图的邻接矩阵
void TopoOrder(int L[n+1][n+1])
{Queue Q;int v, w;int nodecnt;MakeNull(Q);int indegree[n+1];for(int i = 1; i <= n; i++){indegree[i] = 0;}for(int i = 1; i <= n; i++){for(int j = 1; j <= n; j++){if(L[i][j])indegree[j]++;}}for(int i = 1; i <= n; i++){if(indegree[i] == 0)EnQueue(i, Q);}while(!Empty(Q)){nodecnt++;w = Front(Q);cout << w << endl;DeQueue(Q);for(int i = 1; i <= n; i++){if(L[w][i]){indegree[i]--;if(indegree[i] == 0){EnQueue(i, Q);}}}}if(nodecnt != n)cout << "有环!" << endl;
}

第5章 查找

//二分查找
int BinarySearch(keytype k, int last, LIST F) //F是一个升序数组
{int low, up, mid;low = 0; up = last-1;while(low <= up){mid = (low+up)/2;if(F[mid].key == k)return mid;else if(k < F[mid].key)low = mid + 1;else up = mid - 1;  }return -1; //没有找到
}

第6章 内部排序

  1. 希尔排序
void ShellSort(int n, LIST A)
{int i, j, d;for(d = n/2; d >= 1; d/=2){for(i = d+1; i <= n; i++){A[0].key = A[i].key;j = i-d;while(j > 0 && A[j].key > A[0].key){A[j+d] = A[j];j -= d;}A[j+d] = A[0];}}
}
  1. 快速排序
//选取pivot, 选前两个相异元素中较大的
int FindPivot(LIST A, int i, int j)
{keytype firstkey = A[i].key;for(int k = i+1; k <= j; k++){if(A[k].key > firstkey)return k;else if(A[k].key < firstkey)return i;}return 0; //没有不同关键字
}//划分
int Partition(LIST &A, int i, int j, keytype pivot)
{int l = i, r = j;do{swap(A[i], A[j]);while(A[r].key >= pivot)r--;while(A[l].key < pivot)l++;}while(l <= r);return l;
}//快排
void QuickSort(LIST &A, int i, int j)
{keytype pivot;int pivotindex;int k;pivotindex = FindPivot(A, i, j);if(pivotindex != 0){if(pivotindex != i)swap(A[i], A[pivotindex]);pivot = A[i].key;k = Partition(A, i, j, pivot);QuickSort(A, i, k-1);QuickSort(A, k, j);}
}
  1. 堆排序
//将堆顶元素下推到合适的位置,这里假设使用最小堆
void PushDown(LIST &A, int first, int last)
{int r = first;while(r <= last/2){if(r == last/2 && last%2 == 0){ //如果r只有左孩子if(A[r].key > A[2*r].key)swap(A[r], A[2*r]);r = last; //结束循环}else if(A[r].key > A[2*r].key && A[2*r] <= A[2*r+1]){//大于左儿子,且左儿子小于右儿子swap(A[r], A[2*r]); r = 2*r;}else if(A[r].key > A[2*r+1].key && A[2*r+1].key < =A[2*r].jey){//大于右儿子,且右儿子小于左儿子swap(A[r], A[2*r]); r = 2*r;}else{//符合堆的定义r = last; //结束循环}}
}//堆排序
void HeapSort(int n, LIST &A)
{int i;for(i = n/2; i >= 1; i--){ //初始建堆PushDown(D, i, n);}for(i = n; i >= 2; i--){swap(A[1], A[i]); PushDown(A, 1, i-1);}
}
  1. 基数排序
void RadixSort(int figure, Queue &A)
{Queue Q[10];records data;int pass, r;for(pass = 1; pass <= figure; pass++){for(i = 0; i <= 9; i++)MakeNull(Q[i]);while(!Empty(A)){data = DeQueue(A);r = Radix(data.key, pass); //取出data的第pass为数字EnQueue(Q[r], data);}//开始收集for(i = 0; i <= 9; i++){while(!Empty(Q[i])){data = DeQueue(Q[i]);EnQueue(A, data);}}}
}

数据结构经典算法集锦相关推荐

  1. 数据结构常见算法集锦

    数据结构经典算法集锦 第2章 线性表 KMP算法 //获得next数组 void GetNext(char *t, int next[MAX]) {int i = 1, j = 0;next[1] = ...

  2. STL经典算法集锦之排列(next_permutation/prev_permutation

    STL经典算法集锦之排列(next_permutation/prev_permutation) 来自:CSDN博客推荐文章 | 时间:2012-05-07 14:54:09 原文链接: http:// ...

  3. java 数据结构经典算法

    程序1]   题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第四个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少?   1.程序分析:   兔子的规律为 ...

  4. 数据结构经典算法(8)八皇后

    说明:西洋棋中的皇后可以直线前进,吃掉遇到的所有棋子,如果棋盘上有八个皇后,则这八 个皇后如何相安无事的放置在棋盘上,1970年与1971年, E.W.Dijkstra与N.Wirth曾经用这个问 题 ...

  5. 数据结构经典算法(4)三色旗

    说明: 三色旗的问题最早由 E.W.Dijkstra所提出,他所使用的用语为 Dutch Nation Flag(Dijkstra为荷兰 人),而多数的作者则使用Three-Color Flag来称之 ...

  6. 数据结构经典算法学习之八枚银币(简单决策树)

    八枚银币 故事背景: 现有八枚银币a b c d e f g h,已知其中一枚是假币,其重量不同于真币,但不知是较轻或较重,如何使用天平以最少的比较次数,决定出哪枚是假币,并得知假币比真币较轻或较重. ...

  7. 经典高斯算法,一起学习数据结构和算法吧!

    为什么80%的码农都做不了架构师?>>>    对于想提高编程技巧的人,数据结构和算法是必修的,举一个最经典的故事向新手们说明算法的伟大. 话说很久很久以前...,一次数学课上,老师 ...

  8. 数据结构与算法笔记 —— 十大经典排序及算法的稳定性

    一.十大经典排序算法 排序算法是<数据结构与算法>中最基本的算法之一. 排序算法可以分为内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全 ...

  9. 【数据结构与算法】多种语言(VB、C、C#、JavaScript)系列数据结构算法经典案例教程合集目录

    文章目录 1. 专栏简介 2. 专栏地址 3. 专栏目录 1. 专栏简介 2. 专栏地址 「 刘一哥与GIS的故事 」之<数据结构与算法> 3. 专栏目录 [经典回放]多种语言系列数据结构 ...

最新文章

  1. leaq c 汇编语言,汇编语言lea指令使用方法解析
  2. Installshield建立IE快捷方式的方法
  3. mysql4函数,mysql笔记4_函数_MySQL
  4. 巧用“记事本”程序让病毒白白运行
  5. 古谚、评论与论断、名篇与名言
  6. 【渝粤教育】国家开放大学2018年春季 0471-22T畜牧学 参考试题
  7. 自学单片机编程(三) 流水灯代码
  8. win7分区软件_全自动分区装系统PE纯净无广告
  9. iOS系统玩ONS游戏的详细说明(越狱,非越狱)
  10. YUI:globle object
  11. 宝峰c1对讲机写频软件_宝峰对讲机写频软件
  12. 【MapReduce运行报错】Type mismatch inkey form map:excepted org.apache.hadoop.io.Text,recived MR.wordcount.
  13. simm计算机专业英语翻译,计算机专业英语翻译
  14. phpstorm运行php项目步骤
  15. android FTP上传下载文件
  16. html 中二维数组创建,【百度】js基础任务2-二维数组,dom操作
  17. 这是一份激励自己的文章
  18. robotframework基础入门:(2):常见问题对应方法
  19. 一、ECMAScript 6/7/8简介
  20. 1044 火星数字 ——c实现

热门文章

  1. GB50174-2017新旧对比
  2. mro python_用python实现MRO算法
  3. 计算机审计中级培训结业考试,第二期计算机审计中级培训班结业考.doc
  4. 成功解决.append方法出现错误IndexError: list index out of range
  5. 成功解决ValueError: Cannot feed value of shape (1, 10, 4) for Tensor Placeholder:0 , which has shape
  6. Py之xlutils:xlutils的简介、安装、使用方法之详细攻略
  7. ML之k-NN:k-NN实现对150朵共三种花的实例的萼片长度、宽,花瓣长、宽数据统计,根据一朵新花的四个特征来预测其种类
  8. linux下的/dev/shm/ 以及与swap目录的区别【转】
  9. ubuntu在不重装系统情况下关于调整分区,或是从现有根目录划分/home等分区
  10. 三十九、Android原理 不需要关闭后台运行程序