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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

数据结构与算法随学随记

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

1.數據結構是一門研究非數值計算的程序設計問題中的操作對象,以及它們之間的關系和操作等相關問題的學科.

2.傳統上,我們把數據結構分為邏輯結構和物理結構。

邏輯結構:是指數據對象中數據元素之間的相互關系。

物理結構:是指數據的邏輯結構在計算機中的存儲形式。

3.集合結構:集合結構中的數據元素除了同屬于一個集合外,它們之間沒有其他不三不四的關系。

線性結構:線性結構中的數據元素之間是一對一的關系。

樹形結構:樹形結構中的數據元素之間存在一對多的層次關系。

圖形結構:圖形結構的數據元素是多對多的關系。

4.存儲器主要是針對內存而言的,像硬盤、軟盤、光盤等外部存儲器的數據組織通常用文件結構來描述。

6.數據元素的存儲結構形式有兩種:順序存儲和鏈式存儲

順序存儲結構:是把數據元素存放在地址連續的存儲單元里,其數據間的邏輯關系和物理關系是一致的。

7.clock():捕捉從程序開始運行到clock()被調用時所耗費的時間。這個時間單位是clock tick,即“時鐘打點”。

常數CLK_TCK:機器時鐘每秒所走的時鐘大點數。

用法模板:

?

#include<stdio.h> #include<time.h>clock_t start,stop; //clock_t是clock()函數返回的變量類型 double duration; //記錄被測函數運行時間,以秒為單位 int main() {//不在測試范圍內的準備工作寫在clock()調用之前start=clock();//開始計時MyFunction();//把被測函數加在這里stop=clock();duration=((double)(stop-start))/CLK_TCK;//其他不再被測范圍的處理寫在后面,例如輸出duration的值return 0; View Code

8.什么是好的算法:

(1)空間復雜度S(n):根據算法寫成的程序在執行時占用存儲單元的長度。

(2)時間復雜度T(n):根據算法寫成的程序在執行時耗費時間的長度。

在分析一般算法的效率時,我們經常關注下面兩種復雜度

(1)最壞情況復雜度Tworst(n)

(2)平均復雜度Tavg(n)

? ? ? ? ? ? ? ? ? ? ? ? Tavg(n)<=Tworst(n)

9.復雜度常用函數比較大小:

1<logn<n<nlog2n<n2<n3<2n<n!

10.鏈表結點的定義:

鏈表的結點有兩個域:一個是數據域,用來存放數據;另一個是指針域,用來存放下一個結點的位置,如圖所示:

因此,鏈表的結構型定義如下:

typedef struct Node{int data;//這里默認的是int型,如需其他類型那個可直接修改struct Node *next;//指向Node型變量的指針 }Node; View Code

11.二叉樹結點的定義:

typedef struct BTNode{int data;struct BTNode *lchild;struct BTNode *rchild;}BTNode; View Code

12.線性表:由一組數據元素構成,數據元素的位置只取決于自己的序號,元素之間的相對位置是線性的。在復雜線性表中,由若干項數據元素組成的數據元素成為記錄,而由多個記錄構成的線性表又稱為文件。

非空線性表的結構特性:

(1)有且只有一個根節點a1,它無前件。

(2)有且只有一個終端結點an,它無后件

(3)除根節點和終端節點外,其他所有節點有且只有一個前件,也有且只有一個后件。節點個數n為線性表的長度,當n=0時,稱為空表。

13.線性表的順序存儲結構具有以下兩個基本特點:

(1)線性表中所有元素的所占存儲空間是練習的;

(2)線性表中各數據元素再存儲空間中是按邏輯順序依次存放的。

ai?的存儲地址:

ADR(ai)=ADR(ai)+(i-1)K,ADR(ai)為第一個元素的地址,K代表每個元素所占的字節數。

14.順序表的插入運算:

插入的過程:

首先處理3種異常情況:

(1)當存儲空間已滿時為“上溢”錯誤,不能插入,算法結束;

(2)當i>n時,認為在最后一個元素之后插入;

(3)當i<n時,認為在第一個元素之前插入。

然后從最后一個元素開始,直到第i個元素,其中每一個元素均往后移動一個位置。

最后將新元素插入到第i個位置,并且將線性表的長度增加1。

15.順序表的刪除元素

刪除的過程:

首先處理一下2種異常情況:

(1)當線性表為空(即n=0)時即為“上溢”錯誤,算法結束;

(2)當i<1或i>n時,

然后從第i+1個元素開始,直到最后一個元素,其中每個元素依次向前移動一個位置。

最后將線性表的長度減少1。

16.所有的指針變量只占4個字節,用第一個字節的地址表示整個變量的地址。

17.順序表不像鏈表一樣在結點中存在指針域,因此存儲密度大。插入運算方便和刪除運算方便是鏈表的優點。線性表的順序存儲結構必須占用一片連續的存儲空間,而鏈表不需要這樣。順序表不便于元素的插入和刪除,因為要移動多個元素。鏈表在插入和刪除的過程中不需要移動元素,只需修改指針。線性表是具有相同特性數據元素的一個有序序列。

18.靜態鏈表中指針指示的是鏈表中下一元素在數組中的地址。雖然靜態鏈表用數組來存儲,但其指針域和一般單鏈表一樣,指出了表中下一個結點的位置。靜態鏈表具有鏈表的的插入和刪除方便的特點,也不需要移動較多的元素,這是優于順序表的地方。

19.KMP算法

(1)字符串查找問題:給定文本串text和模式串pattern,從文本串text中找出模式串pattern第一次出現的位置

(2)最基本的字符串匹配算法:暴力求解(Brute Force):時間復雜度O(m*n)

(3)KMP算法是一種線性時間復雜度的字符串匹配算法,它是對BF算法改進。

(4)記:文本串長度為N,模式串長度為M

(I)BF算法的時間復雜度O(M*N),空間復雜度O(1);

(II)KMP算法的時間復雜度O(M+N),空間復雜度O(N);

(5)KMP算法的核心就是避免不必要的回溯,那么什么事不必要的呢?問題由模式串決定,不是由目標決定。

(6)分析BF與KMP的區別

(I)假設當前文本串text匹配到i位置,模式串pattern串匹配到j位置

(II)BF算法中,如果當前字符串匹配成功,即text[i+j]==pattern[j],令i++,j++,繼續匹配下一個字符;如果失敗,即text[i+j]=/=(不等于)pattern[j],令i++,j=0;即每次匹配失敗的情況下,模式串pattern相對于文本串text向右移動了一位。

(7)KMP算法中,如果當前字符匹配成功,即text[i+j]==pattern[j],令i++,j++,繼續匹配下一個字符;如果失敗,即text[i+j]=/=(不等于)pattern[j],令i不變,j=next[j],(這里,next[j]<=j-1),即模式串pattern相對于文本串text向右移動了至少1位(移動的實際位數j-next[j]>=1)。

(8)在暴力求解中,為什么模式串的索引會回溯?

因為模式串存在重復字符。

(9)對于模式串的位置j,考察Patternj-1=P0P1...Pj-2Pj-1,查找字符串Patternj-1最大相等k前綴和k后綴。注:計算next[j]時,考察的字符串是模式串的前j-1個字符,與pattern[j]無關。即:查找慢走條件的最大的k,是得P0P1...Pk-2Pk-1?=Pj-kPj-k+1...Pj-2Pj-1?。

(10)next的遞推關系:

(I)對于模式串的位置j,有next[j]=k,即:P0P1...Pk-2Pk-1?=Pj-kPj-k+1...Pj-2Pj-1?

(II)則,對于模式串的位置j+1,考察Pj;

(III)若p[k]==p[j]?

  next[j+1]=next[j]+1

(IV)若p[k]=/=p[j],記h=next[k];如果p[h]==p[j],則next[j+1]=h+1,否則重復此過程。

(11)進一步分析next

(I)文本串匹配到i,模式串匹配到j,此時,若text[i]=/=pattern[j],即匹配失敗的情況:

(II)若next[j]=k,說明模式串應該從j滑動到k位置;

(III)若此時滿足pattern[j]==pattern[k],因為text[i]=/=pattern[j],所以,text[i]=/=pattern[k]

(i)即i和k沒有匹配,應該繼續滑動到next[k]。

(ii)換句話說:若原始的next數組中,若next[j]=k并且pattern[j]==pattern[k],next[j]可以直接等于next[k]。

(12)代碼

//BF算法,暴力算法 int index(Str str,Str substr) {int i=0,j=0,k=i;while(i<str.length&&j<substr.length){if(str.ch[i]==substr.ch[j]){++i;++j;}else{j=0;i=++k;//匹配失敗,i從主串下一位置開始,k種記錄了上一次的啟示位置 }}if(j==substr.length)return k;else return -1; } //KMP算法 int KMP(Str str,Str substr,int next[]) {int i=0,j=0;while(i<str.length&&j<substr.length){if(str.ch[i]==substr.ch[j]){++i;++j;}else{j=next[i];if(j==-1){j=0;++i;}}}if(j==substr.length)return i-substr.length;else return -1; } 求next數組的算法如下 void getnext(Str sbustr,int next[]) {int i=0;j=-1;next[0]=-1;while(i<substr.length){if(j==-1||substr.ch[i]==sbustr.ch[j]){++i;++j;next[i]=j;}elsej=next[j];} } View Code

20.

(1)串是限定了數據元素是字符的線性表,串的數據元素必須是單個字符

(2)串的兩種最基本存儲方式是順序存儲方式和鏈式存儲方式。

(3)空格字符也是串中的一個字符。

21.希爾排序

#include<stdio.h> #include<math.h> #define MAXNUM 10//希爾排序void shellSort(int array[],int n,int t){int a,dk;for(a=1;a<=t;a++){dk=(int)(pow(2,t-a+1)-1);//計算增量 int i,j,temp;for(i=dk;i<n;i++)//分別向每組的有序區域進行插入 {temp=array[i];for(j=i-dk;(j>=i%dk)&&array[j]>temp;j-=dk)//比較與記錄后移同時進行array[j+dk]=array[j];if(j!=i-dk)array[j+dk]=temp;//插入 } }} void main(){void shellSort(int array[],int n,int t);//t為排序的趟數int array[MAXNUM],i;for(i=0;i<MAXNUM;i++)scanf("%d",&array[i]);shellSort(array,MAXNUM,(int)(log(MAXNUM+1)/log(2)));//排序趟數應為long2(n+1)的整數部分for(i=0;i<MAXNUM;i++)printf("%d ",array[i]);printf("\n"); } View Code

22.進行冒泡排序

#include <stdio.h> #include <stdlib.h>#define MAXNUM 10 /* run this program using the console pauser or add your own getch, system("pause") or input loop */void maopaoInsert(int R[],int n) {int i,j,temp;for(j=0;j<n-1;j++)//總共需要排序的次數 {for(i=0;i<n-1-j;i++)//此趟需要排序的個數,也就是從0 .....n-1-j。進行比較 {if(R[i]>R[i+1])//每次進行兩兩比較 {temp=R[i];R[i]=R[i+1];R[i+1]=temp;}}}} void main(){int array[MAXNUM],i;for(i=0;i<MAXNUM;i++)scanf("%d",&array[i]);maopaoInsert(array,MAXNUM);//排序趟數應為long2(n+1)的整數部分for(i=0;i<MAXNUM;i++)printf("%d ",array[i]);printf("\n"); } View Code

23快速排序

#include <stdio.h> #include <stdlib.h>#define MAXNUM 10void kuaisuSort(int a[],int left,int right) {if(left>=right)//如果左邊索引大于或者等于右邊的索引就代表已經整理完成一個組了 {return; } int i=left;int j=right;int key=a[left];//以a[left]為軸中心while(i<j)//控制在當組內尋找一遍 {while(i<j&&key<=a[j])//而尋找結束的條件就是,1,找到一個小于或者大于key的數,沒有符合條件1的,并且i與j的大小沒有反轉 {j--;//向前尋找 } a[i]=a[j];// 找到一個這樣的數后就把他賦給前面的被拿走的i的值(如果第一次循環且key是a[left],那么就是key) while(i<j&&key>=a[i])//這是i在當組內向前尋找,同上,不過注意與key的大小關系停止循環和上面相反,因為排序思想就是把數組網兩邊礽,所以左右兩邊的數大小與key的關系相反 {i++;}a[j]=a[i];} a[i]=key;//當在當組內找完一遍以后就把中間數key回歸kuaisuSort(a,left,i-1);//最后用同樣的方式把對分出來的左邊的小組進行同上的做法kuaisuSort(a,i+1,right);//最后用同樣的方式把對分出來的右邊的小組進行同上的做法 //當然最后可能會出現很多分左右,直到每一組的i=j為止。 } void main(){int array[MAXNUM],i;for(i=0;i<MAXNUM;i++)scanf("%d",&array[i]);kuaisuSort(array, 0,MAXNUM-1); for(i=0;i<MAXNUM;i++)printf("%d ",array[i]);printf("\n"); } View Code

24.簡單選擇排序

#include <stdio.h> #include <stdlib.h>#define MAXNUM 10 /* run this program using the console pauser or add your own getch, system("pause") or input loop */void jiandanxuanzeSort(int R[],int n) {int i,j,min;int minR;//儲存最小的數組 int temp;for(i=0;i<n;i++){minR=R[i];////假設R[i]為本輪最小值 min=i;//將 最小值下標存儲在min中 for(j=i+1;j<n;j++)//從i到n查找最小值 {if(R[j]<minR)//如果有R[j]小于最小值 {minR=R[j];//那么把R[j]賦值給minR行調換 min=j;}}//將尋找到的最小值R[min]與本輪的R[i]對換 temp=R[i];R[i]=R[min];R[min]=temp;} }void main(){int array[MAXNUM],i;for(i=0;i<MAXNUM;i++)scanf("%d",&array[i]);jiandanxuanzeSort(array,MAXNUM); for(i=0;i<MAXNUM;i++)printf("%d ",array[i]);printf("\n"); } View Code

25.最大公約數

//最大公約數 int gcd(int v1,int v2) {while(v2){int temp=v2;v2=v1%v2;v1=temp; } return v1; } View Code

26.交換

(1)指針

#include <iostream>using namespace std;void swap(int *px, int *py) {int temp;temp=*px;*px=*py;*py=temp; }int main() {int a,b;a = 1;b = 10;cout << "傳指針的方法: " << endl;cout << "a = " << a << ", b = " << b << endl;//拷貝的指針(地址) swap(&a,&b);cout << "a = " << a << ", b = " << b << endl;return 0; } View Code

(2)宏函數

#include <iostream>#define SWAP(x,y,t) ((t)=(x),(x)=(y),(y)=(t)) using namespace std;int main() {int a, b, temp;a = 1;b = 10;cout << "使用宏定義函數: " << endl;cout << "a = " << a << ", b = " << b << endl;SWAP(a,b,temp);cout << "a = " << a << ", b = " << b << endl;return 0; } View Code

(3)引用

#include <iostream>using namespace std;//引用就是別名 void swap(int &a,int &b) {int temp;temp=a;a=b;b=temp;} int main() {int a,b;a = 1;b = 10;cout << "傳引用: " << endl;cout << "a = " << a << ", b = " << b << endl;swap(a,b);cout << "a = " << a << ", b = " << b << endl;return 0; } View Code

(4)C++標準庫 swap

#include <iostream>using namespace std;int main() {int a, b;a = 1;b = 10;cout << "使用std::swap函數: " << endl;cout << "a = " << a << ", b = " << b << endl;std::swap(a,b);cout << "a = " << a << ", b = " << b << endl;return 0; } View Code

27.圖

(1)鄰接矩陣

代碼:

#include <iostream>using namespace std;#define MAX_VERTS 20 //保存最多的頂點數 //頂點 class Vertex {public:Vertex(char lab){Label=lab; } private:char Label;};//圖 鄰接矩陣 (對稱) class Graph {public:Graph();~Graph();void addVertex(char lab);//增加頂點 void addEdge(int start,int end);//增加邊void printMatrix();//打印矩陣 private:Vertex* vertexList[MAX_VERTS];//數組(保存最多的定點數) int nVerts;//實際上的頂點數 int adjMat[MAX_VERTS][MAX_VERTS]; //鄰接矩陣 } ;//構造函數,有效點為0,初始化矩陣 Graph::Graph() {nVerts=0;for(int i=0;i<MAX_VERTS;i++){for(int j=0;j<MAX_VERTS;j++){adjMat[i][j]=0;} }} //增加點 void Graph::addVertex(char lab){vertexList[nVerts++]=new Vertex(lab);}// 增加邊 (對稱) void Graph::addEdge(int start,int end){adjMat[start][end]=1;adjMat[end][start]=1;}//打印 void Graph::printMatrix(){for(int i=0;i<nVerts;i++){for(int j=0;j<nVerts;j++){cout<<adjMat[i][j]<<" ";}cout<<endl;}}//析構函數 Graph::~Graph(){for(int i=0;i<nVerts;i++){delete vertexList[i];}} int main() {Graph a;a.addVertex('A');//下標 0 a.addVertex('B');//下標 1a.addVertex('C');//下標 2 a.addVertex('D');//下標 3 a.addVertex('E');//下標 4 a.addEdge(0,1);//連線 A-B a.addEdge(0,3);//連線 A-D a.addEdge(1,0);//連線 B-A a.addEdge(1,4);//連線 B-E a.addEdge(2,4);//連線 C-Ea.addEdge(3,0);//連線 D-Aa.addEdge(3,4);//連線 D-Ea.addEdge(4,1);//連線 E-B a.addEdge(4,2);//連線 E-C a.addEdge(4,3);//連線 E-D a.printMatrix(); return 0; } View Code

(2)鄰接表

#include <iostream> #include <list>using namespace std;class Vertex { public:char Label;Vertex(char lab) { Label = lab; } };ostream& operator<<(ostream& out, const Vertex& v) {cout << v.Label;return out; }template<class T> class Graph { public:Graph(const int vertices) : n(vertices){VertexList = new T*[n];HeadNodes = new list<int>[n];nVerts = 0;}~Graph(){delete[] VertexList;delete[] HeadNodes;}void addVertex(T* v);void addEdge(int start, int end);void printVertice();void printAdjList(); private:T** VertexList;list<int>* HeadNodes;int n;int nVerts; };template<class T> void Graph<T>::addVertex(T* v) {VertexList[nVerts++] = v; }template<class T> void Graph<T>::addEdge(int start, int end) {HeadNodes[start].push_back(end); }template<class T> void Graph<T>::printVertice() {for(int i=0; i<nVerts; i++)cout << *VertexList[i] << " ";cout << endl; }template<class T> void Graph<T>::printAdjList() {for(int i=0; i<nVerts; i++){cout << i << " -> ";for(list<int>::iterator iter = HeadNodes[i].begin(); iter != HeadNodes[i].end(); ++iter)cout << *iter << " -> ";cout << "end" << endl;} }int main() {//Graph<char> g(5);//char a = 'A';//char b = 'B';//char c = 'C';//char d = 'D';//char e = 'E';Graph<Vertex> g(5);Vertex a('A');Vertex b('B');Vertex c('C');Vertex d('D');Vertex e('E');g.addVertex(&a);g.addVertex(&b);g.addVertex(&c);g.addVertex(&d);g.addVertex(&e);g.printVertice();g.addEdge(0,1);g.addEdge(0,3);g.addEdge(1,0);g.addEdge(1,4);g.addEdge(2,4);g.addEdge(3,0);g.addEdge(3,4);g.addEdge(4,1);g.addEdge(4,2);g.addEdge(4,3);g.printAdjList();system("pause");return 0; } View Code

(3)深度優先搜索(DFS) 使用堆棧

?

代碼:(以鄰接矩陣圖形為案例)

#include <iostream> #include<stack>#define MAX_VERTS 20using namespace std;class Vertex { public:Vertex(char lab) { Label = lab; wasVisited=false;//新構造的頂點沒有訪問過 } public:bool wasVisited; char Label; };class Graph { public:Graph();~Graph();void addVertex(char lab);void addEdge(int start, int end);void printMatrix();void showVertex(int v);//顯示頂點 void DFS();//深度優先搜索 private:Vertex* vertexList[MAX_VERTS];int nVerts;int adjMat[MAX_VERTS][MAX_VERTS];int getAdjUnvisitedVertex(int v); //獲得臨接的下一個且沒有訪問的頂點 };void Graph::DFS() {stack<int> gStack;vertexList[0]->wasVisited=true;//頂點 showVertex(0);gStack.push(0);//頂點放入到堆棧 int v;while(gStack.size()>0){v=getAdjUnvisitedVertex(gStack.top());//總是以堆棧中最上一個為準 if(v==-1)// 如果沒有,則返回 gStack.pop();else//找到 {vertexList[v]->wasVisited=true;showVertex(v);gStack.push(v); //找到放入到堆棧中 }}cout<<endl;for(int j=0;j<nVerts;j++)//設置false 可以多次進行搜索 vertexList[j]->wasVisited=false; }//獲得臨接的下一個且沒有訪問的頂點 //是否是鄰接的?是否訪問過 int Graph::getAdjUnvisitedVertex(int v) {for(int j=0;j<nVerts;j++)if((adjMat[v][j]==1)&&(vertexList[j]->wasVisited==false))return j;return -1; } void Graph::showVertex(int v) {cout<<vertexList[v]->Label<<" "; } Graph::Graph() {nVerts = 0;for(int i=0; i<MAX_VERTS; i++)for(int j=0; j<MAX_VERTS; j++)adjMat[i][j] = 0; }void Graph::addVertex(char lab) {vertexList[nVerts++] = new Vertex(lab); }void Graph::addEdge(int start, int end) {adjMat[start][end] = 1;adjMat[end][start] = 1; }void Graph::printMatrix() {for(int i=0; i<nVerts; i++){for(int j=0; j<nVerts; j++)cout << adjMat[i][j] << " ";cout << endl;} }Graph::~Graph() {for(int i=0; i<nVerts; i++)delete vertexList[i]; }int main() {Graph g;g.addVertex('A');// 0g.addVertex('B');// 1g.addVertex('C');// 2g.addVertex('D');// 3g.addVertex('E');// 4 g.addEdge(0,1); // A-Bg.addEdge(0,3); // A-Dg.addEdge(1,0); // B-Ag.addEdge(1,4); // B-Eg.addEdge(2,4); // C-Eg.addEdge(3,0); // D-Ag.addEdge(3,4); // D-Eg.addEdge(4,1); //E-B g.addEdge(4,2);//E-Cg.addEdge(4,3);//E-D g.printMatrix();cout << "深度優先搜索的結果: ";g.DFS();system("pause");return 0; } View Code

?

(4)廣度優先搜索(BFS) 使用隊列

?

?代碼:

#include <iostream> #include <stack> #include<queue> #define MAX_VERTS 20using namespace std;class Vertex { public:Vertex(char lab) { Label = lab; wasVisited = false;} public:bool wasVisited;char Label; };class Graph { public:Graph();~Graph();void addVertex(char lab);void addEdge(int start, int end);void printMatrix();void showVertex(int v);void DFS();void BFS();//廣度優先 private:Vertex* vertexList[MAX_VERTS];int nVerts;int adjMat[MAX_VERTS][MAX_VERTS];int getAdjUnvisitedVertex(int v); };void Graph::DFS() {stack<int> gStack;vertexList[0]->wasVisited = true;showVertex(0);gStack.push(0);int v;while(gStack.size() > 0){v = getAdjUnvisitedVertex(gStack.top());if(v == -1)gStack.pop();else{vertexList[v]->wasVisited = true;showVertex(v);gStack.push(v);}}cout << endl;for(int j=0; j<nVerts; j++)vertexList[j]->wasVisited = false; }void Graph::BFS() {queue<int>gQueue;vertexList[0]->wasVisited=true; //設置頂點為訪問過了,showVertex(0);gQueue.push(0);//把頂點放入到隊列中 int vert1,vert2;while(gQueue.size()>0){vert1=gQueue.front();//把隊列中頂點拿出來 gQueue.pop();//隊列頂點刪除 vert2=getAdjUnvisitedVertex(vert1);//鄰接且沒有訪問過的 while(vert2!=-1)//有 鄰接且沒有訪問過的 {vertexList[vert2]->wasVisited=true;showVertex(vert2);gQueue.push(vert2);//放入到隊列中 vert2=getAdjUnvisitedVertex(vert1);//繼續尋找vert1中其他符合條件的//(因為getAdjUnvisitedVertex這個函數只是保證找到符合條件就返回) }} cout<<endl;for(int j=0; j<nVerts; j++)vertexList[j]->wasVisited = false;} int Graph::getAdjUnvisitedVertex(int v) {for(int j=0; j<nVerts; j++)if((adjMat[v][j] == 1) && (vertexList[j]->wasVisited == false))return j;return -1; }void Graph::showVertex(int v) {cout << vertexList[v]->Label << " "; }Graph::Graph() {nVerts = 0;for(int i=0; i<MAX_VERTS; i++)for(int j=0; j<MAX_VERTS; j++)adjMat[i][j] = 0; }void Graph::addVertex(char lab) {vertexList[nVerts++] = new Vertex(lab); }void Graph::addEdge(int start, int end) {adjMat[start][end] = 1;adjMat[end][start] = 1; }void Graph::printMatrix() {for(int i=0; i<nVerts; i++){for(int j=0; j<nVerts; j++)cout << adjMat[i][j] << " ";cout << endl;} }Graph::~Graph() {for(int i=0; i<nVerts; i++)delete vertexList[i]; }int main() {Graph g;g.addVertex('A');// 0g.addVertex('B');// 1g.addVertex('C');// 2g.addVertex('D');// 3g.addVertex('E');// 4 g.addEdge(0,1); // A-Bg.addEdge(0,3); // A-Dg.addEdge(1,0); // B-Ag.addEdge(1,4); // B-Eg.addEdge(2,4); // C-Eg.addEdge(3,0); // D-Ag.addEdge(3,4); // D-Eg.addEdge(4,1); // E-B g.addEdge(4,2); // E-Cg.addEdge(4,3); // E-D g.printMatrix();cout << "深度優先搜索的結果: ";g.DFS();cout << "廣度優先搜索的結果: ";g.BFS();cout <<endl;system("pause");return 0; } View Code

28.紅黑樹

(1)紅黑樹特征:節點都有顏色,插入和刪除節點時要遵循紅黑規則

(2)紅黑規則:

(I)每一個節點不是紅色的就是黑色的。

(II)根總是黑色的

(III)如果節點時紅色的,則它的子節點必須是黑色的

(IV)從根到葉節點的每條路徑,必須包含相同數目的黑色節點。

(3)修正方法

(I) 修改節點的顏色

(II)旋轉

(4)C++標準庫中的紅黑樹

#include <set> #include <map>using namespace std;int main() {//C++標準庫容器(數據結構):紅黑樹set<int> a;multiset<int> b;map<int,int> c;multimap<int,int> d;a.insert(50);a.insert(40);a.insert(30);return 0; } View Code

(5)紅黑樹(自編)

#include <iostream> #include <sstream> #include <string> #include <vector>// SEE UPDATE COMMENTS AT END OF FILE // 2006-01.29 fixed memory leaks// eliminate need to qualify standard library with std:: using namespace std;// =============================================================== // C++ NEEDS SOME DECLARATIONS BEFORE THE MAIN RedBlackTree class. // skip down a little to line this up with the other side // =============================================================== // requires forward declaration to resolve cycle between NodeVisitor and RedBlackTree template<class T> class RedBlackTree;// use an abstract class for the node visitor. it is templatized to match the templated RedBlackTree declaration template<class T> class NodeVisitor { public:// need a virtual destructor for the concrete classesvirtual ~NodeVisitor() {}// ise a pure virtual function so a concrete class must implement// the proper signaturevirtual void visit(const RedBlackTree<T> *node,int depth) = 0; };// ============================================= // >>>>>>>>>>>>>>>>> RED BLACK TREE STARTS HERE // ============================================= // in line with the STL conventions, this template uses 'by-value' semantics for the contained // object. This means that the 'T' object will need to have the correct constructor and copy assignment // semantics or it won't work. primitive types are OK but object instances would have to be // put together correctly. template<class T> class RedBlackTree {private: /*Red/Black tree implementation based on Algorithms in C++, SedgewickIntroduction To Algorithms Cormen, Thomas H. / Leiserson, Charl es E . / Rivest, Ronald L . The MIT Press 07/1990NOTE : LOOK AT END OF FILE TO SEE DIFFERENCES IN TRAVERSAL IDIOMS */// yes, i could use an enum but since i want to print the values, using an enum is more// trouble than it is worth.static const int red = 0;static const int black = 1;// use a common instance variable naming convention 'm_'. others use a single leading '_'int m_color;T m_val;RedBlackTree *m_left;RedBlackTree *m_right;RedBlackTree(RedBlackTree *b) {m_val = b->m_val;m_left = b->m_left;m_right = b->m_right;m_color = red;}void copy(RedBlackTree *x) {m_val = x->m_val;m_left = x->m_left;m_right = x->m_right;m_color = x->m_color;// UPDATE 2006-01-28// node pointed to by 'x' is no longer needed, delete it. // first make sure the delete won't descend into other nodesx->m_left = 0;x->m_right = 0;delete x;}RedBlackTree *RBinsertLeft(T k,int sw) {RedBlackTree *l;RedBlackTree *b;l = m_left;if (l == 0) {m_left = b = new RedBlackTree(k);}else {b = l->RBinsert(k,sw);}return b;}RedBlackTree *RBinsertRight(T k,int sw) {RedBlackTree *r;RedBlackTree *b;r = m_right;if (r == 0) {m_right = b = new RedBlackTree(k);}else {b = r->RBinsert(k,sw);}return b;}RedBlackTree *rotLeft(){RedBlackTree *x;RedBlackTree *me;if (m_right == 0) return 0;// make the changes in a copy of current node __self// on return, the caller will copy in 'me' to current nodeme = new RedBlackTree(this);x = me->m_right;me->m_right = x->m_left;x->m_left = me;return x;}RedBlackTree *rotRight(){RedBlackTree *x;RedBlackTree *me;if (m_left == 0) return 0;// make the changes in a copy of current node __self// on return, the caller will copy in 'me' to current nodeme = new RedBlackTree(this);x = me->m_left;me->m_left = x->m_right;x->m_right = me;return x;}RedBlackTree *RBinsert(T k,int sw) {RedBlackTree *b = 0;RedBlackTree *x;RedBlackTree *l;RedBlackTree *ll;RedBlackTree *r;RedBlackTree *rr;// if current node is a 4 node, split it by flipping its colors// if both children of this node are red, change this one to red// and the children to blackl = m_left;r = m_right;if ((l != 0)&&(l->m_color==red)&&(r != 0)&&(r->m_color==red)) {m_color = red;l->m_color = black;r->m_color = black;}// go left or right depending on key relationshipif (k < m_val) {// recursively insertb = RBinsertLeft(k,0);// on the way back up check if a rotation is needed// if search path has two red links with same orientation// do a single rotation and flip the color bitsl = m_left;if ((m_color == red)&&(l != 0)&&(l->m_color == red)&&(sw == 1)) {x = rotRight();if (x != 0) {// copy returned node to 'this' copy(x);}}// flip the color bitsl = m_left;if (l != 0) {ll = l->m_left;if (ll != 0) {if ((l->m_color == red)&&(ll->m_color == red)) {x = rotRight();if (x != 0) {copy(x);}m_color = black;r = m_right;if (r != 0) {r->m_color = red;}}}}}else {b = RBinsertRight(k,1);// on the way back up check if a rotation is needed// if search path has two red links with same orientation// do a single rotation and flip the color bitsr = m_right;if ((m_color == red)&&(r != 0)&&(r->m_color == red)&&(sw == 0)) {x = rotLeft();if (x != 0) {// copy returned node to 'this' copy(x);}}// flip the color bitsr = m_right;if (r != 0) {rr = r->m_right;if (rr != 0) {if ((r->m_color == red)&&(rr->m_color == red)) {x = rotLeft();if (x != 0) {// copy returned node to 'this' copy(x);}m_color = black;l = m_left;if (l != 0) {l->m_color = red;}}}}} return b;}// ================================================== // PUBLIC METHODS // ================================================== public:// construct with an initial value RedBlackTree(T x) {m_val = x;m_left = 0;m_right = 0;m_color = red;}~RedBlackTree() {if (m_left != 0) {delete m_left;}if (m_right != 0) {delete m_right;}}// return a string representation string str() const {stringstream s(stringstream::out);// m_val (type T) must have the proper ostream insertion operator// or this implementation won't works << "[" << m_val << "," << m_color << "]";return s.str();}// 'const' means this method doesn't change the object stateT val() const {return m_val;}// 'const' means this method doesn't change the object stateint color() const {return m_color;}// 'const' means this method doesn't change the object state// and it returns a pointer to a const node that the caller// cannot change, only inspectconst RedBlackTree *find(const T &key) const {const RedBlackTree *result = 0;if (key == m_val) {result = this;}else if (key < m_val) {if (m_left != 0) {result = m_left->find(key);}}else {if (m_right != 0) {result = m_right->find(key);}}return result;}// 'const' means this method doesn't change the object state// and the visitor is not allowed to change the object state.// that may not be what is desired but is used here to // illustrate something you can do in C++ that you can't do// in the other languages and that illustrates the bias towards// extensive static type checkingvoid inorder(NodeVisitor<T> *visitor,int depth) const {if (m_left != 0) {m_left->inorder(visitor,depth+1);}visitor->visit(this,depth);if (m_right != 0) {m_right->inorder(visitor,depth+1);}}RedBlackTree *insert(T k) {RedBlackTree *b;b = RBinsert(k,0);m_color = black;return b;} };// define a concrete class for the node visitor class IntNodeVisitor : public NodeVisitor<int> { public:virtual ~IntNodeVisitor() {}// the node is 'const' so the visitor can't change it, only look at itvirtual void visit(const RedBlackTree<int> *node,int depth) {if (node->val() != 0) {cout << "(" << node->val() << ":" << node->color() << ":" << depth << "), ";}} };// ================================== // test program // ================================== int main(int argc,char *argv[]) {int nodelist[] = {11,4,8,14,17,6,9,7,16,15,13,5,19,18,12,10,3,20,1};NodeVisitor<int> *v;// anonymous class implementing the NodeVisitor interfacev = new IntNodeVisitor;// insert all the data into the treeRedBlackTree<int> *root = new RedBlackTree<int>(2);root->insert(11);root->insert(4);root->insert(8);root->insert(14);root->insert(17);root->insert(6);//顯示紅黑樹里的數據root->inorder(v,0);return 0;// need to do an ugly calculation to figure out length of the nodelist array// if i used a collection object instead of an array, then I couldn't have// done static initialization. so its a tradeofffor(int i=0;i<(sizeof(nodelist)/sizeof(nodelist[0]));i++) {root->insert(nodelist[i]);}// print the headercout << "C++ = "; // visit all the nodes in orderroot->inorder(v,0);// print a newlinecout << endl;// find the specified element and print its valueconst RedBlackTree<int> *x = root->find(16);cout << x->str() << endl;// no garbage collection, need to explicitly deletedelete root; // will recursively delete all the nodesdelete v; }// =================================================================== // UPDATE 2006-01-29 // there are memory leaks that need to be fixed. // 1. the algorithm leaks nodes after a rotate // two possible fixes : // find where the leaks occur and do the needed deletes // in this case the 'copy' method handles // deleting unused nodes // use an appropriate smart pointer to handle deleteing // 2. the tree is not properly disposed of when the program completes // In the STL tradition a delete of the tree should // delete all tree resources but not the contained data. the application // should handle deleting the contained data elements, if needed, prior // to deleting the tree. In this case a recursive delete of the // nodes works gets rid of the tree resources // // these issue show that one of the big difficulties in C++ is to // handle disposing of data after you are done with it. that is indeed a // source of many C++ program errors of the type that are related more to // dealing with the complexity of the language rather than the solving // the problem. In this code the leaks are probably fixed but there is always // a lingering doubt "Did I get all the leaks?" // Thats a problem with C++, its hard to be certain. // // a modern approach is to use smart pointers to simulate garbage // collection. the Boost library referenced counted smart pointers // will be included in the next standard revision of the C++ library // so they are used here to handle all the cases. // =================================================================== View Code

(6)紅黑樹(模版)

#ifndef RED_BLACK_TREE_H_ #define RED_BLACK_TREE_H_#include "Wrapper.h" #include "Except.h"// Red-black tree class. // // CONSTRUCTION: with negative infinity object // // ******************PUBLIC OPERATIONS********************* // void insert( x ) --> Insert x // void remove( x ) --> Remove x (unimplemented) // Comparable find( x ) --> Return item that matches x // Comparable findMin( ) --> Return smallest item // Comparable findMax( ) --> Return largest item // bool isEmpty( ) --> Return true if empty; else false // void makeEmpty( ) --> Remove all items // ******************ERRORS******************************** // Throws exceptions as warranted. template <class Comparable> class RedBlackTree;template <class Comparable> class RedBlackNode;template <class Comparable> class RedBlackTree {public:RedBlackTree( const Comparable & negInf );RedBlackTree( const RedBlackTree & rhs );~RedBlackTree( );Cref<Comparable> findMin( ) const;Cref<Comparable> findMax( ) const;Cref<Comparable> find( const Comparable & x ) const;bool isEmpty( ) const;void makeEmpty( );void insert( const Comparable & x );void remove( const Comparable & x );enum { RED, BLACK };const RedBlackTree & operator=( const RedBlackTree & rhs );typedef RedBlackNode<Comparable> Node;private:Node *header; // The tree header (contains negInf)Node *nullNode;// Used in insert routine and its helpers (logically static)Node *current;Node *parent;Node *grand;Node *great;// Usual recursive stuffvoid reclaimMemory( Node *t ) const;RedBlackNode<Comparable> * clone( Node * t ) const;// Red-black tree manipulationsvoid handleReorient( const Comparable & item );RedBlackNode<Comparable> * rotate( const Comparable & item,Node *parent ) const;void rotateWithLeftChild( Node * & k2 ) const;void rotateWithRightChild( Node * & k1 ) const; };template <class Comparable> class RedBlackNode {Comparable element;RedBlackNode *left;RedBlackNode *right;int color;RedBlackNode( const Comparable & theElement = Comparable( ),RedBlackNode *lt = NULL, RedBlackNode *rt = NULL,int c = RedBlackTree<Comparable>::BLACK ): element( theElement ), left( lt ), right( rt ), color( c ) { }friend class RedBlackTree<Comparable>; };// Construct the tree. // negInf is a value less than or equal to all others. template <class Comparable> RedBlackTree<Comparable>::RedBlackTree( const Comparable & negInf ) {nullNode = new Node;nullNode->left = nullNode->right = nullNode;header = new Node( negInf );header->left = header->right = nullNode; }// Copy constructor. template <class Comparable> RedBlackTree<Comparable>::RedBlackTree( const RedBlackTree<Comparable> & rhs ) {nullNode = new Node;nullNode->left = nullNode->right = nullNode;header = new Node( rhs.header->element );header->left = header->right = nullNode;*this = rhs; }// Destroy the tree. template <class Comparable> RedBlackTree<Comparable>::~RedBlackTree( ) {makeEmpty( );delete nullNode;delete header; }// Insert item x into the tree. // Throws DuplicateItemException if x is already present. template <class Comparable> void RedBlackTree<Comparable>::insert( const Comparable & x ) {current = parent = grand = header;nullNode->element = x;while( current->element != x ){great = grand; grand = parent; parent = current;current = x < current->element ? current->left : current->right;// Check if two red children; fix if soif( current->left->color == RED && current->right->color == RED )handleReorient( x );}// Insertion fails if already presentif( current != nullNode )throw DuplicateItemException( );current = new Node( x, nullNode, nullNode );// Attach to parentif( x < parent->element )parent->left = current;elseparent->right = current;handleReorient( x ); }// Remove item x from the tree. // Not implemented in this version. template <class Comparable> void RedBlackTree<Comparable>::remove( const Comparable & x ) {cout << "Sorry, remove unimplemented; " << x <<" still present" << endl; }// Find the smallest item the tree. // Return the smallest item wrapped in a Cref object. template <class Comparable> Cref<Comparable> RedBlackTree<Comparable>::findMin( ) const {if( isEmpty( ) )return Cref<Comparable>( );Node *itr = header->right;while( itr->left != nullNode )itr = itr->left;return Cref<Comparable>( itr->element ); }// Find the largest item in the tree. // Return the largest item wrapped in a Cref object. template <class Comparable> Cref<Comparable> RedBlackTree<Comparable>::findMax( ) const {if( isEmpty( ) )return Cref<Comparable>( );Node *itr = header->right;while( itr->right != nullNode )itr = itr->right;return Cref<Comparable>( itr->element ); }// Find item x in the tree. // Return the matching item wrapped in a Cref object. template <class Comparable> Cref<Comparable> RedBlackTree<Comparable>::find( const Comparable & x ) const {nullNode->element = x;Node *curr = header->right;for( ; ; ){if( x < curr->element )curr = curr->left;else if( curr->element < x )curr = curr->right;else if( curr != nullNode )return Cref<Comparable>( curr->element );elsereturn Cref<Comparable>( );} }// Make the tree logically empty. template <class Comparable> void RedBlackTree<Comparable>::makeEmpty( ) {reclaimMemory( header->right );header->right = nullNode; }// Test if the tree is logically empty. // Return true if empty, false otherwise. template <class Comparable> bool RedBlackTree<Comparable>::isEmpty( ) const {return header->right == nullNode; }// Deep copy. template <class Comparable> const RedBlackTree<Comparable> & RedBlackTree<Comparable>::operator=( const RedBlackTree<Comparable> & rhs ) {if( this != &rhs ){makeEmpty( );header->right = clone( rhs.header->right );}return *this; }// Internal method to clone subtree. template <class Comparable> RedBlackNode<Comparable> * RedBlackTree<Comparable>::clone( Node * t ) const {if( t == t->left ) // Cannot test against nullNode!!!return nullNode;elsereturn new RedBlackNode<Comparable>( t->element, clone( t->left ),clone( t->right ), t->color ); }// Internal routine that is called during an insertion // if a node has two red children. Performs flip and rotations. // item is the item being inserted. template <class Comparable> void RedBlackTree<Comparable>::handleReorient( const Comparable & item ) {// Do the color flipcurrent->color = RED;current->left->color = BLACK;current->right->color = BLACK;if( parent->color == RED ) // Have to rotate {grand->color = RED;if( item < grand->element != item < parent->element )parent = rotate( item, grand ); // Start dbl rotatecurrent = rotate( item, great );current->color = BLACK;}header->right->color = BLACK; // Make root black }// Internal routine that performs a single or double rotation. // Because the result is attached to the parent, there are four cases. // Called by handleReorient. // item is the item in handleReorient. // parent is the parent of the root of the rotated subtree. // Return the root of the rotated subtree. template <class Comparable> RedBlackNode<Comparable> * RedBlackTree<Comparable>::rotate( const Comparable & item,Node *theParent ) const {if( item < theParent->element ){item < theParent->left->element ?rotateWithLeftChild( theParent->left ) : // LLrotateWithRightChild( theParent->left ) ; // LRreturn theParent->left;}else{item < theParent->right->element ?rotateWithLeftChild( theParent->right ) : // RLrotateWithRightChild( theParent->right ); // RRreturn theParent->right;} }// Rotate binary tree node with left child. template <class Comparable> void RedBlackTree<Comparable>:: rotateWithLeftChild( Node * & k2 ) const {Node *k1 = k2->left;k2->left = k1->right;k1->right = k2;k2 = k1; }// Rotate binary tree node with right child. template <class Comparable> void RedBlackTree<Comparable>:: rotateWithRightChild( Node * & k1 ) const {Node *k2 = k1->right;k1->right = k2->left;k2->left = k1;k1 = k2; }// Internal method to reclaim internal nodes in subtree t. template <class Comparable> void RedBlackTree<Comparable>::reclaimMemory( Node *t ) const {if( t != t->left ){reclaimMemory( t->left );reclaimMemory( t->right );delete t;} }#endif View Code

?29.冒泡排序

(1)從左到右掃描數據,選擇最大的數據,放在右邊。

(2)要點:比較相鄰的兩個樹,如果左邊的數大于右邊的數就進行交換。

(3)代碼:

#include <iostream>using namespace std;void BubbleSort(int list[], int n);int main() {int a[] = {2,4,6,8,0,1,3,5,7,9};BubbleSort(a,10);for(int k=0; k<10; k++)cout << a[k] << " ";cout << endl;return 0; }void BubbleSort(int list[], int n) {for(int i=0; i<n-1; i++){for(int j=0; j<n-i-1;j++){if(list[j] > list[j+1])std::swap(list[j],list[j+1]);}} } View Code

30選擇排序

(1)從當前未排序的整數中找一個最小的整數,將它放在已排序的整數列表的最后。

(2)要點:選擇排序最小的,往左邊選。

#include <iostream>using namespace std;void SelectSort(int *a, const int n);int main() {int x[] = {1,3,5,7,9,0,2,4,6,8};SelectSort(x,10);for(int k=0; k<10; k++)cout << x[k] << endl;return 0; }void SelectSort(int *list, const int n) {// i<nfor(int i=0; i<n-1; i++){int min = i; //min就是毛巾,毛巾是數組的下標for(int j=i+1; j<n; j++){if(list[j] < list[min])min = j;}swap(list[i],list[min]);} } View Code

31.折半查找

v#include <iostream>using namespace std;int BinarySearch(int *a, const int x, const int n); int BinSearch(int *a, const int x, const int n);int main() {int x[] = {1,2,3,4,5,6,7,8,9,10};int 結果;int num;num = 6;結果 = BinSearch(x, num, 10);if(結果 < 0)cout << "沒找到! " << endl;elsecout << "在x[" << 結果 << "]找到" << num << endl;return 0; }int BinSearch(int *a, const int x, const int n) {int left = 0, right = n-1;while(left<=right){int middle = (left + right)/2;if(x < a[middle]) right = middle-1;else if(x > a[middle]) left=middle+1;else return middle;}return -1; }int BinarySearch(int *a, const int x, const int n) {int low, high, mid;low = 0, high = n-1;while(low<=high){mid = (low + high) / 2;if(a[mid] == x)return mid;else if(a[mid] < x)low = mid+1;else if(a[mid] > x)high = mid - 1;}return -1; } View Code #include <iostream>using namespace std;int BinarySearch_I(int *a, const int x, const int n); int BinarySearch_R(int *a, const int x, const int left, const int right);int main() {int m[] = {1,2,3,4,5,6,7,8,9};int 結果;int num = 7;if((結果 = BinarySearch_R(m,num,0,8))<0){cout << "遞歸算法: 沒找到!" << endl;}else{cout << "遞歸算法: 在m[" << 結果 << "]找到" << num << endl;}if((結果 = BinarySearch_I(m,num,9))<0){cout << "迭代算法: 沒找到!" << endl;}else{cout << "迭代算法: 在m[" << 結果 << "]找到" << num << endl;}return 0; }int BinarySearch_I(int *a, const int x, const int n) {int left = 0, right = n-1;while(left <= right){int middle = (left+right)/2;if(x<a[middle]) right = middle-1;else if(x>a[middle]) left = middle + 1;else return middle;}return -1; }int BinarySearch_R(int *a, const int x, const int left, const int right) {if(left<=right){int middle = (left+right)/2;if(x<a[middle]) return BinarySearch_R(a,x,left,middle-1);else if(x>a[middle]) return BinarySearch_R(a,x,middle+1,right);else return middle;}return -1; } View Code

32.排列組合

#include <iostream>using namespace std; //字符,開始的下標,最后的下標 void Permutations(char *p,const int k,const int m) {//k的變換, Permutations(p,k+1,m)中的k+1賦值給了k if(k==m)//已經到了最后一個,不需要遞歸 {cout<<"ddddddddddddd"<<endl;for(int i=0;i<=m;i++)cout<<p[i];cout<<endl; } else{for(int i=k;i<=m;i++ ){swap(p[k],p[i]);//調換開頭 abc,讓 a,b,c依次開頭 Permutations(p,k+1,m);//加入確定了 a 繼續讓bc依次遞歸 swap(p[k],p[i]);//還原 } } }int main() {char s[]="abc";Permutations(s,0,2); return 0; } View Code

33.快速排序

#include <iostream>using namespace std;template<class T> void QuickSort(T *a, const int left, const int right) {if(left<right){//選樞軸int i = left;int j = right+1; //為什么要加一?int pivot = a[left];//劃分算法do{do i++; while(a[i]<pivot);do j--; while(a[j]>pivot);if(i<j) swap(a[i],a[j]);}while(i<j);swap(a[left],a[j]);QuickSort(a,left,j-1);QuickSort(a,j+1,right);} }int main() {int k[] = {8,6,4,2,0,1,3,5,7,9,99};QuickSort(k,0,9);for(int i=0; i<10; i++)cout << k[i] << endl;return 0; } View Code

34.約瑟夫問題

據說著名猶太歷史學家Josephus有過以下的故事:在羅馬人占領喬塔帕特后,39個猶太人與Josephus以及他的朋友多到一個洞中,39個猶太人決定死也不要被敵人抓住,于是決定了一個自殺方式,41個人排成一個園圈,由第1個人開始報數,每報道第3個個就必須自殺,然后再由下一個重新報數,直到所有人自殺身亡為止。

然而Josephus和它的朋友安排在第16個和第31個為止,于是逃過了這場死亡游戲。

程序模擬給出了死亡游戲自殺順序。

//n個人圍圈報數,報m出列,最后剩下的是幾號? #include <stdio.h> #include <stdlib.h>typedef struct node {int data;//存儲了排列的序號。struct node *next; }node;//創建循環鏈表 node *create(int n) {node *p = NULL, *head;head = (node*)malloc(sizeof (node ));p = head;node *s;int i = 1;if( 0 != n ){//尾后插入法while( i <= n ){s = (node *)malloc(sizeof (node));s->data = i++; // 為循環鏈表初始化,第一個結點為1,第二個結點為2。p->next = s;p = s;}s->next = head->next;//最后一個節點指向第一個節點(不是頭節點) }free(head);//刪除頭節點return s->next ;//返回第一個節點 }int main() {int n = 41;int m = 3;int i;node *p = create(n);node *temp;m %= n; // m在這里是等于3while (p != p->next )//鏈表剩下最后一個 {for (i = 1; i < m-1; i++)//找到第一個節點 {p = p->next ;//p指向第二節點 }printf("%d->", p->next->data );//打印第三個節點的數值 temp = p->next ; //刪除第m個節點p->next = temp->next ;free(temp);p = p->next ;//p是第四個節點 }printf("%d\n", p->data );//打印最后一個return 0; } View Code

?

轉載于:https://www.cnblogs.com/heisaijuzhen/p/4285274.html

《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀

總結

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

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