【数据结构】大连理工大学软件学院20年
生活随笔
收集整理的這篇文章主要介紹了
【数据结构】大连理工大学软件学院20年
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
最小生成樹
#include<iostream> #include <stdlib.h> #define INF 1000000 using namespace std;//MinHeaptemplate <class T> class MinHeap { private:T* heapArray;int CurrentSize; /* 當前堆元素個數 */int MaxSize; /* 堆中能存放的最大元素個數 */ public:MinHeap(T* array, int num, int max){this->heapArray = array;this->CurrentSize = num;this->MaxSize = max;}MinHeap(int num){this->MaxSize=num;this->CurrentSize=0;heapArray=new T[num];}virtual ~MinHeap() {};bool isLeaf(int pos) const;int leftchild(int pos) const;int rightchild(int pos) const;int parent(int pos) const;void BuildHeap(); /* 2.4-a 最大堆構建 */void SiftDown(int left); /* 2.4-b SiftDown函數從left向下調整堆,使序列成為堆 */void SiftUp(int pos); /* 2.4-c SiftUp函數從position向上調整堆,使序列成為堆 */bool Remove(int pos, T& node); /* 2.4-d 刪除給定下標的元素 */bool Insert(const T& newNode); /* 2.4-e 從堆中插入新元素newNode */T& RemoveMin(); /* 2.4-f 從堆頂刪除最大值 */void visit(); };/** TODO:2.4-a 最大堆構建*/ template <class T> void MinHeap<T>::BuildHeap() {for (int i = CurrentSize/2 - 1;i >= 0;i--) {SiftDown(i);} }template <class T> bool MinHeap<T>::isLeaf(int pos) const {if (pos >= CurrentSize) {cout << "越界" << endl;return (false);}else if (pos > (CurrentSize - 1) / 2)return (true);elsereturn (false); }template <class T> int MinHeap<T>::leftchild(int pos) const {return (2 * pos + 1); }template <class T> int MinHeap<T>::rightchild(int pos) const {return (2 * pos + 2); }template <class T> int MinHeap<T>::parent(int pos) const {return ((pos - 1) / 2); }/** TODO:2.4-d 刪除給定下標的元素,并將該元素的值賦值給node變量。* 返回值說明:如果刪除成功,則返回true,否則返回false* 重要說明:如果當前堆為空,則輸出打印cout << "空堆" << endl;并返回false*/ template <class T> bool MinHeap<T>::Remove(int pos, T& node) {if (CurrentSize == 0) {cout << "空棧" << endl;return false;}int i = pos;node = heapArray[pos];heapArray[i] = heapArray[CurrentSize - 1];CurrentSize--;SiftDown(i);SiftUp(i);return true; }/** TODO:2.4 - b SiftDown函數從left向下調整堆,使序列成為堆*/ template <class T> void MinHeap<T>::SiftDown(int left) {int i = left;int j = 2 * i + 1;T temp = heapArray[i];while (j < CurrentSize) {if ((j < CurrentSize - 1) && (heapArray[j] > heapArray[j + 1]))j++;if (temp > heapArray[j]) {heapArray[i] = heapArray[j];i = j;j = 2 * j + 1;}else break;}heapArray[i] = temp; }/** TODO:2.4-c SiftUp函數從pos向上調整堆,使序列成為堆*/ template <class T> void MinHeap<T>::SiftUp(int pos) {int i = pos;int j = (i - 1) / 2;T temp = heapArray[i];while (j >= 0 && i >= 1) {if (heapArray[i] < heapArray[j]) {heapArray[i] = heapArray[j];i = j;j = (j - 1) / 2;}else break;}heapArray[i] = temp; }/** TODO:2.4-e 從堆中插入新元素newNode, 如果插入成功,返回true,否則返回false。* 重要說明:如果堆中元素超過堆中元素最大個數值,則輸出打印cout << "堆滿" << endl;并返回false*/ template <class T> bool MinHeap<T>::Insert(const T& newNode) {if (CurrentSize == MaxSize) {cout << "堆滿" << endl;return false;}else {CurrentSize++;heapArray[CurrentSize - 1] = newNode;BuildHeap();} }template <class T> void MinHeap<T>::visit() {for (int i = 0; i < CurrentSize; i++)cout << heapArray[i] << " ";cout << endl; }/** TODO:2.4-f 從堆頂刪除最大值. 如果堆棧為空堆,則輸出打印cout << "空堆" << endl;然后退出程序,退出碼為1.* 否則,從堆頂刪除最大值,并將其作為返回值進行返回。*/ template <class T> T& MinHeap<T>::RemoveMin() {if (CurrentSize == 0){cout << "空棧" << endl;exit(1);}else {T temp = heapArray[0];heapArray[0] = heapArray[CurrentSize - 1];CurrentSize--;if (CurrentSize > 1)SiftDown(0);return temp;} }//template<class EdgeType> class Edge { public:int start;int end;int weight;Edge(int s = 0, int e = 0, int w = 0) {start = s;end = e;weight = w;}bool operator >(Edge oneEdge) {return weight > oneEdge.weight;}bool operator <(Edge oneEdge) {return weight < oneEdge.weight;} };class Graph { public:int vNum;int eNum;int* Mark;Graph(int vnum) {vNum = vnum;eNum = 0;Mark = new int[vNum];for (int i = 0;i < vNum;i++) {Mark[i] = 0;}}~Graph() {delete[] Mark;}virtual Edge firstEdge(int oneVertex) = 0;virtual Edge nextEdge(Edge oneEdge) = 0;bool IsEdge(Edge oneEdge) {if (oneEdge.weight > 0 && oneEdge.weight < INF && oneEdge.end >= 0)return true;elsereturn false;}int StartVertex(Edge oneEdge) {return oneEdge.start;}int EndVertex(Edge oneEdge) {return oneEdge.end;}int weight(Edge oneEdge) {return oneEdge.weight;}virtual void setEdge(int start, int end, int weight) = 0;virtual void delEdge(int start, int end) = 0;};//template<class EdgeType> class AdjGraph :public Graph { private:int** matrix; public:AdjGraph(int vnum) :Graph(vnum) {matrix = (int**)new int* [vnum];for (int i = 0;i < vnum;i++) {matrix[i] = new int(vnum);}for (int i = 0;i < vnum;i++) {for (int j = 0;j < vnum;j++) {matrix[i][j] = 0;}}}~AdjGraph() {for (int i = 0;i < vNum;i++) {delete[] matrix[i];}delete[]matrix;}Edge firstEdge(int oneVertex) {//查找以 oneVertex為起點的第一條邊 Edge temp;for (int i = 0;i < vNum;i++) {if (matrix[oneVertex][i] != 0 && matrix[oneVertex][i] != INF) {temp.weight = matrix[oneVertex][i];temp.end = i;break;}}temp.start = oneVertex;return temp;}Edge nextEdge(Edge oneEdge) {//返回與oneEdge共始點的下一條邊 Edge temp;int start = oneEdge.start, end = oneEdge.end;temp.start = start;for (int i = end + 1;i < vNum;i++) {if (matrix[start][i] != 0 && matrix[start][i] != INF) {temp.weight = matrix[start][i];temp.end = i;break;}}return temp;}void setEdge(int start, int end, int weight) {if (matrix[start][end] == 0) {eNum++;}matrix[start][end] = weight;}void delEdge(int start, int end) {if (matrix[start][end] != 0) {matrix[start][end] = 0;eNum--;}}};class UFsets{ private:int n;//等價類中 等價元的個數int *root;//root[i]表示元素i所在的等價類的代表元素編號int *next;//next[i]表示在等價類中,i的后面元素編號int *length;//length[i]表示i所代表的 等價類的元素個數 public:UFsets(int size){n = size;//初始size個元素的等價類root = new int[n];next = new int[n];length = new int[n];for (int i = 0; i < n; i++){root[i] = next[i] = i;//各個元素獨自成一個等價類length[i] = 1;}}int Find(int v){if (v < n){return root[v];}//返回等價類中的代表元素編號else{//邊界檢查cout << "參數不合法" << endl;}}void Union(int v, int u);//合并v和u所在的等價類,將元素少的合并到元素多的里面去 }; void UFsets::Union(int v, int u){if (root[u] == root[v]){//如果兩個在同一個等價類中,就返回return;}else if (length[root[v]] <= length[root[u]]){//如果u的長度比v的長度長,那么就把v合到u里面去int rt = root[v];//記錄rt值 length[root[u]] = length[root[u]] + length[root[v]];//修改u所在的等價類的元素的個數root[rt] = root[u];//下面來修改v所在的等價類里面的元素的代表元素for (int j = next[rt]; j != rt; j = next[j]){root[j] = root[u];}//下面交換兩個代表元素 rt,root[u] 的next值int temp;temp = next[rt];next[rt] = next[root[u]];next[root[u]] = temp;}else if (length[root[v]] > length[root[u]]){//相反的一樣int rt = root[u];length[root[v]] = length[root[v]] + length[root[u]];root[rt] = root[v];for (int k = next[rt]; k != rt; k = next[k]){root[k] = root[v];}//swapint temp;temp = next[rt];next[rt] = next[root[v]];next[root[v]] = temp;} }//template<class EdgeType> Edge* Kruskal(AdjGraph& G){//最小生成樹的Kruskal算法//求含有n個頂點、e條邊的連通圖G的最小生成樹 返回邊的集合int n = G.vNum;//記錄頂點數目UFsets sets(n);//定義n個結點的等價類Edge *MST = new Edge[n - 1];//要返回的最小生成樹的邊MinHeap<Edge> MinH(G.eNum);//定義含有e個元素的最小堆,用于尋找權值最小的邊Edge edge;for (int i = 0; i < n; i++){for (edge = G.firstEdge(i); G.IsEdge(edge); edge = G.nextEdge(edge)){if (G.StartVertex(edge) < G.EndVertex(edge)){//限制起始點的編號大小順序,防止無向圖中的邊被重復加入MinH.Insert(edge);}}}int edgeNum = 0;//生成邊的個數while (edgeNum < n - 1){//n個結點的連通圖的生成樹有n-1條邊//if (!MinH.isEmpty()){//如果堆不空edge = MinH.RemoveMin();//找到權重最小的未處理的邊 int v = edge.start;int u = edge.end;if (sets.Find(v) != sets.Find(u)){//判斷該邊關聯的頂點是否在一個連通分量sets.Union(v, u);//合并兩個頂點所在的等價類MST[edgeNum] = edge;//將符合條件的邊添加到生成樹的邊集合中edgeNum++;}/*}else{assert("不存在最小生成樹.");return nullptr;}*/}return MST; }int main(){AdjGraph g(6); g.setEdge(0,1,6);g.setEdge(1,0,6);g.setEdge(0,2,1);g.setEdge(2,0,1);g.setEdge(0,3,5);g.setEdge(0,5,5);g.setEdge(1,2,5);g.setEdge(2,1,5);g.setEdge(2,3,5);g.setEdge(3,2,5);g.setEdge(1,4,3);g.setEdge(4,1,3);g.setEdge(2,4,6);g.setEdge(4,2,6);g.setEdge(4,5,6);g.setEdge(5,4,6);g.setEdge(2,5,4);g.setEdge(5,2,4);g.setEdge(3,5,2);g.setEdge(5,3,2);Edge* q=Kruskal(g);cout<<"kruskal:"<<endl;for(int i=0;i<g.vNum-1;i++){cout<<"("<<q[i].start<<","<<q[i].end<<","<<q[i].weight<<")"<<endl;}delete []q;return 0; }圖的遍歷
/*3.3 圖的遍歷a. 深度優先搜索(DFS):遞歸及非遞歸遞歸 void DFSTraverse() void DFS1(int v)非遞歸 void DFSNoReverse()b. 廣度優先搜索(BFS)void BFSTraverse() void BFS1(int v)*/#include <iostream> #include <queue>//這個是隊列的庫 #include <stack>//這個是棧的庫typedef enum {UNVISITED,VISITED}VISITORNOT;using namespace std;//命名空間template <class T> class Edge { public:int start, end, weight;//始點,終點,權重Edge()//空構造函數,全設0{start = 0;end = 0;weight = 0;}Edge(int st, int en, int w)//三有構造函數{start = st;end = en;weight = w;}void showEdge()//展示邊的唄{cout << "start: " << start << " end:" << end << " weight:" << weight << endl;} };template <class T>//模板啦 class Graph {//圖結構啦 public:int vertexNum; //圖的頂點數目int edgeNum; //圖的邊數目int* Mark;Graph(){vertexNum = 0;edgeNum = 0;Mark = NULL;}Graph(int verticesNum)//構造函數{vertexNum = verticesNum;edgeNum = 0;Mark = new int[vertexNum];for (int i = 0; i < vertexNum; i++)Mark[i] = 0;}~Graph()//析構函數{delete[] Mark;}virtual Edge<T> FirstEdge(int oneVertex) = 0;//返回第一條邊啦,給頂點virtual Edge<T> NextEdge(Edge<T> oneEdge) = 0;//給第一條邊,返回下一條邊int VerticesNum() { return vertexNum; }//返回頂點數int EdgesNum() { return edgeNum; }//返回邊的數量int StartVertex(Edge<T> oneEdge) { return oneEdge.start; }//給一條邊,返回始點int EndVertex(Edge<T> oneEdge) { return oneEdge.end; }//給一條邊,返回終點int Weight(Edge<T> oneEdge) { return oneEdge.weight; }//給一條邊,返回權重virtual void setEdge(int start, int end, int weight) = 0;//設置邊,給起點終點權重virtual void delEdge(int start, int end) = 0; };template <class T> class AdjGraph : public Graph<T> { private:int** matrix;//矩陣指針public:AdjGraph(int verticesNum)//構造函數,給頂點數{int i, j;this->vertexNum = verticesNum;this->edgeNum = 0;this->Mark = new int[verticesNum];for (int i = 0; i < verticesNum; i++)//初始化this->Mark[i] = 0;matrix = (int**)new int* [this->vertexNum];//矩陣初始化for (i = 0; i < this->vertexNum; i++)matrix[i] = new int[this->vertexNum];for (i = 0; i < this->vertexNum; i++)for (j = 0; j < this->vertexNum; j++)matrix[i][j] = 0;}~AdjGraph()//析構函數{for (int i = 0; i < this->vertexNum; i++)delete[] matrix[i];delete[] matrix;}bool isEdge(Edge<T> oneEdge)//判斷是不是一條邊,這個函數好啊,可以用啊,輸入一條邊,{if (oneEdge.weight > 0 && oneEdge.end >= 0)return true;elsereturn false;}Edge<T> FirstEdge(int oneVertex)//第一條邊,給頂點{Edge<T> tempEdge;tempEdge.start = oneVertex;for (int i = 0; i < this->vertexNum; i++) {if (matrix[oneVertex][i] != 0) {tempEdge.end = i;tempEdge.weight = matrix[oneVertex][i];break;}}return tempEdge;}Edge<T> NextEdge(Edge<T> oneEdge)//下一條邊,給邊{Edge<T> tempEdge;tempEdge.start = oneEdge.start;for (int i = oneEdge.end + 1; i < this->vertexNum; i++) {if (matrix[oneEdge.start][i] != 0) {tempEdge.end = i;tempEdge.weight = matrix[oneEdge.start][i];break;}}return tempEdge;}void setEdge(int start, int end, int weight){if (start < this->vertexNum && end < this->vertexNum && weight >= 0) {if (matrix[start][end] == 0) {this->edgeNum++;}matrix[start][end] = weight;}elsecout << "非法輸入" << endl;}void delEdge(int start, int end){if (start < this->vertexNum && end < this->vertexNum) {if (matrix[start][end] != 0)this->edgeNum--;matrix[start][end] = 0;}elsecout << "非法輸入" << endl;}void DFS1(int v){this->Mark[v] = 1; //標記該頂點已訪問cout << v + 1 << " "; //訪問該頂點:頂點0設為1for (Edge<T> e = FirstEdge(v); isEdge(e); e = NextEdge(e)) { //由該點所關聯的邊進行深度優先搜索if (this->Mark[e.end] == 0) //訪問V鄰接到的未被訪問過的頂點,并遞歸地進行深度優先搜索DFS1(e.end);}}/*TODO:a 深度優先搜索(DFS):遞歸,對所有頂點的標志位初始化,檢查圖是否有未訪問的頂點,如果有則從該頂點開始深度優先搜索,對未訪問的頂點調用DFS1*/void DFSTraverse(){for (int i = 0; i < this->VerticesNum(); i++)//初始化{this->Mark[i] = UNVISITED;//這是什么牛逼操作,搞得這么炫酷,沒有什么屌用,把地址里面的東西設置成了這個玩意,設置0它不香嗎????}for (int i = 0; i < this->VerticesNum(); i++){if (this->Mark[i] == UNVISITED){DFS1(i);}}}/*TODO:a 深度優先搜索(DFS):非遞歸.對所有頂點的標志位初始化檢查圖是否有未訪問的頂點,如果有則從該頂點開始深度優先搜索。當遇到未訪問的頂點時,需要輸出打印cout << u + 1 << " "; 。比如當this->Mark[i] == 0;且要處理它時,則通過打印語句cout << i + 1 << " ";將其位置打印出來。 具體可參考測試用例。*/void DFSNoReverse()//這是非遞歸吧{int i, v, u;stack<int> s;//不大明白??????哪兒來的棧??????這不是有包嗎,怎么還用ArrayStackfor (i = 0; i < this->VerticesNum(); i++){this->Mark[i] = UNVISITED;}for (i = 0; i < this->VerticesNum(); i++){if (this->Mark[i] == UNVISITED){s.push(i);cout << i + 1 << " ";//哪來的visitthis->Mark[i] = VISITED;//謎之操作while (!s.empty())//我明白了,這特么庫函數自帶的棧類吧!!!!!{v = s.top();//出個棧,人家沒有返回值,算了,用top吧s.pop();for (Edge<T> e = FirstEdge(v); isEdge(e); e = NextEdge(e))//遍歷邊{u = this->EndVertex(e);//u是終點if (this->Mark[u] == UNVISITED)//沒訪問才干,但是還能重?????{s.push(u);cout << u + 1 << " ";this->Mark[u] = VISITED;}}}}}}/* TODO:BFS1算法,訪問頂點V,并將其標志位置為已訪問,訪問該頂點: 打印cout << v + 1 << " "; 訪問其它未被訪問的頂點時,也打印cout << u + 1 << " ";其中,u是被訪問的頂點*/void BFS1(int v){queue<int> Q;this->Mark[v] = VISITED;//標記該頂點已訪問cout << v + 1 << " "; //訪問該頂點:頂點0設為1Q.push(v);while (!Q.empty()){int i = Q.front();Q.pop();for (Edge<T> e = FirstEdge(i); isEdge(e); e = NextEdge(e))//遍歷{ int u = this->EndVertex(e);if (this->Mark[u] == UNVISITED){cout << u + 1 << " ";this->Mark[u] = VISITED;Q.push(u);}}}}/*TODO:b. 廣度優先搜索(BFS),對所有頂點的標志位初始化.檢查圖中是否有未訪問的頂點,如果有則從該頂點開始調用BFS1進行廣度優先搜索*/void BFSTraverse(){int v;for (v = 0; v < this->VerticesNum(); v++)//遍歷{this->Mark[v] = UNVISITED;}for (v = 0; v < this->VerticesNum(); v++)//遍歷{if (this->Mark[v] == UNVISITED){BFS1(v);}}}void showGraph(){cout << "圖有" << this->edgeNum << "條邊" << endl;cout << "圖的信息為:" << endl;for (int i = 0; i < this->vertexNum; i++) {for (int j = 0; j < this->vertexNum; j++)cout << matrix[i][j] << " ";cout << endl;}} };int main() {Edge<int> tempEdge;int count, start, end, weight;cin >> count;AdjGraph<int> adp(count); //count為圖的頂點數目adp.setEdge(1, 0, 2); //1,0,2 其中1為邊的起點,0為邊的終點,2為邊的權重。adp.setEdge(0, 2, 1);adp.setEdge(0, 3, 3);adp.setEdge(3, 2, 1);adp.setEdge(3, 4, 1);adp.showGraph();cout << "深度優先搜索: ";adp.DFSTraverse();cout << endl;cout << "廣度優先搜索: ";adp.BFSTraverse();cout << endl;return 0; }總結
以上是生活随笔為你收集整理的【数据结构】大连理工大学软件学院20年的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【OriginLab 】OriginPr
- 下一篇: android监听试用,金山手机卫士An