日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

数据结构经典算法集锦

發布時間:2025/3/21 编程问答 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 数据结构经典算法集锦 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

數據結構經典算法集錦

第2章 線性表

  • 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; //沒有匹配成功 }
  • 單向環形鏈表反向
  • //設原來的環形鏈表為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章 樹

  • 二叉樹三種遍歷非遞歸實現
  • //數據結構定義 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; //遍歷右子樹,不再處于回退狀態}}} }
  • 線索二叉樹
  • //數據結構定義 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;} }
  • 哈夫曼樹
  • //數據結構定義 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章 圖

  • 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;}}} }
  • 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);}} }
  • 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;} }
  • 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);} }
  • 拓撲排序算法
  • //輸入圖的鄰接矩陣 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章 內部排序

  • 希爾排序
  • 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];}} }
  • 快速排序
  • //選取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);} }
  • 堆排序
  • //將堆頂元素下推到合適的位置,這里假設使用最小堆 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);} }
  • 基數排序
  • 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);}}} }

    總結

    以上是生活随笔為你收集整理的数据结构经典算法集锦的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。