【資料結構】各類排序演算法的實現
給出n個學生的考試成績表,每條資訊由姓名和成績組成,
試運用各種排序思想設計演算法並比較其效能,要求實現:
a.按分數高低次序,打印出每個學生在考試中獲得的名次,分數相同的為同一名次;
b.按名次列出每個學生的姓名與分數。
#include<stdio.h> #include<string> #include<string.h> #include<iostream> const int N=1e3+10; using namespace std; /* 給出n個學生的考試成績表,每條資訊由姓名和成績組成, 試運用各種排序思想設計演算法並比較其效能,要求實現: a.按分數高低次序,打印出每個學生在考試中獲得的名次,分數相同的為同一名次; b.按名次列出每個學生的姓名與分數。*/ typedef struct Node{ double S; string name; bool operator > (const Node & p)const { return S>p.S; } bool operator < (const Node & p)const { return S<p.S; } bool operator <=(const Node & p)const { return S<=p.S; } bool operator >=(const Node & p)const { return S>=p.S; } }Student; typedef Node Type; Student a[N]; int n; /*void swap(Student &a, Student &b){ Student tmp=a; a=b; b=tmp; }*/ void CreateTable(){ cin>>n; for(int i=1;i<=n;i++){ cin>>a[i].S>>a[i].name; } } void Output(){ for(int i=1;i<=n;i++){ int No=i; if(a[i].S==a[i-1].S){ No--; } cout<<"第"<<No<<"名 為:"; cout<<a[i].S<<" "<<a[i].name<<endl; } } void InsertSort(){ for(int i=1;i<=n;i++){ if(a[i].S>a[i-1].S){ int k=i-1; Student tmp=a[i]; for(int j=k;j>=1&&tmp>a[j];j--){ a[j+1]=a[j]; k--; } a[k+1]=tmp; } } Output(); } void BubbleSort(){ for(int i=1;i<n;i++){ for(int j=1;j<=n-i;j++){ Student tmp; if(a[j]<a[j+1]){ swap(a[j],a[j+1]); /*tmp=a[j]; a[j]=a[j+1]; a[j+1]=tmp;*/ } } } Output(); } void QuickSort(int L,int R){ if(L<R){ int i=L,j=R; Node x=a[L]; while(i<j){ while( i<j && a[j]<x ){ j--; } if(i<j) a[i++]=a[j]; while(i<j&&a[i]>=x){ i++; } if(i<j) a[j--]=a[i]; } a[i]=x; QuickSort(L,i-1); QuickSort(i+1,R); } } void SelectSort(){ for(int i=1;i<n;i++){ int k=i; for(int j=k+1;j<=n;j++){ if(a[k]<a[j]){ k=j; //printf("%f %f \n",a[k].S,a[j].S); } } if(i!=k){ swap(a[i],a[k]); } } Output(); } void MergeSort(Type *t,int L, int R){ int i,j,k; int mid; if(L>=R){ return ; } //*tmp; //可能指標分配出問題,導致程式無法執行 //Type *tmp=(Type *)malloc(sizeof(Type)*(R-L+2)); Type *tmp=new Type[R-L+1]; if(t==NULL){ return ; } if(tmp==NULL){ return; } mid=(L+R)/2; MergeSort(t,L,mid); MergeSort(t,mid+1,R); i=L; j=mid+1; k=0; while( i<=mid && j<=R ){ if(t[i]>t[j]){ tmp[k++]=t[i++]; }else{ tmp[k++]=t[j++]; } } while(i<=mid){ tmp[k++]=t[i++]; } while(j<=R){ tmp[k++]=t[j++]; } for(i=0;i<=R-L;i++){ t[L+i]=tmp[i]; } delete tmp; return; } void AdjustDown(Type a[], int i, int n){ int j=i*2+1; while(j<n){ if(j+1<n&&a[j]>a[j+1]){ j++; } if(a[i]<a[j]) break; swap(a[i],a[j]); i=j; j=i*2+1; } } void MakeHeap(Type *a, int n){ int i=0; for(i=n/2-1;i>=0;i--){ AdjustDown(a,i,n); } } void HeapSort(Type a[], int n){ int i=0; MakeHeap(a,n); for(i=n-1;i>=0;i--){ swap(a[i],a[0]); AdjustDown(a,0,i); } } int main() { CreateTable(); //InsertSort(); //BubbleSort(); //QuickSort(1,n); Output(); //SelectSort(); //MergeSort(a,1,n); Output(); Student b[N]; for(int i=0;i<n;i++){ b[i]=a[i+1]; } HeapSort(b,n); for(int i=0;i<n;i++){ int No=i+1; if(b[i].S==b[i-1].S){ No--; } cout<<"第"<<No<<"名 為:"; cout<<b[i].S<<" "<<b[i].name<<endl; } return 0; } /* 5 10 a 6 b 8 d 7 c 10 e */ /* //除錯歸併排序 Student b[N]; for(int i=0;i<n;i++){ b[i]=a[i+1]; } MergeSort(b,0,n-1); for(int i=0;i<n;i++){ int No=i+1; if(b[i].S==b[i-1].S){ No--; } cout<<"第"<<No<<"名 為:"; cout<<b[i].S<<" "<<b[i].name<<endl; } */
相關推薦
【資料結構】各類排序演算法的實現
給出n個學生的考試成績表,每條資訊由姓名和成績組成, 試運用各種排序思想設計演算法並比較其效能,要求實現: a.按分數高低次序,打印出每個學生在考試中獲得的名次,分數相同的為同一名次; b.按名次列出每個學生的姓名與分數。 #include<stdio.h>
【資料結構】各類排序演算法及其優化總結
本文對各類排序演算法的實現、優化、複雜度、穩定性、適用場景作以全面總結,為了突出演算法的簡潔、易懂,去除了一些冗餘操作,預設為升序進行模擬。 一、插入排序 插入排序基本思想:每一步將一個待排序的元素,按其排序碼的大小,插入到前面已經排好序的一組元素的合適位置
【資料結構】歸併排序-python實現
【資料結構】歸併排序--python 實現時間複雜度程式碼實現執行示例 歸併排序介紹 快速排序是典型的使用分治的思想來解決問題的演算法。分治策略會將原問題劃分為n個規模較小而結構與原問題相似的子問題。遞迴地解決這些子問題,然後再合併其結果,就得到原問題的解。
【資料結構】--2.排序演算法
常見的排序演算法 :氣泡排序 、選擇排序、插入排序、歸併排序、快速排序、堆排序 https://www.cnblogs.com/eniac12/p/5329396.html #include<iostream> using namespace std; v
SWUST資料結構--希爾排序演算法實現
#include<iostream> using namespace std; int main(){ int i,n; int a[50]; cin>>n; for(i=0;i<n;i++) cin>>a[i]; for(i=0;i<
【資料結構】計數排序
概念: 計數排序,又稱為鴿巢原理,是對雜湊定址法的變形應用。 核心思想是: 具體程式碼如下: void CountSort(int* a, int n)//計數排序 { int max = a[0]; int min = a[0]; for (in
【資料結構】選擇排序
概念: 每次從待排序的陣列元素中,選出最小或最大的,存放在序列的起始位置,直到全部待排序的陣列元素排完。 核心思想: 如果有n個元素需要排序,首先從n個元素中找到最小的那個元素,並與第0個位置上的元素交換,最大的那個元素與最後一個位置上的數交換(說明一點,如果沒有比第
【資料結構】鄰接矩陣及其實現
檔案操作比直接輸入方便很多 直接輸入: //建立圖的鄰接矩陣儲存結構 #include <stdio.h> #include <string.h> #define M 20 #define FINITY 5000 typedef struct { char
【資料結構】八大排序之氣泡排序
氣泡排序:(升序為例) 利用兩個for迴圈每次比較相鄰的兩個元素,如果前一個元素比後一個元素大則交換兩個數。外層的for迴圈控制排序的總趟數,內層的for迴圈控制每一趟的相鄰兩個數的比較的次數 我們很輕易的看出: 氣泡排序的時間複雜度最
【資料結構】順序佇列的實現(C語言)
佇列的基本概念及其描述 佇列是一種特殊的線性表,它的特殊性在於佇列的插入和刪除操作分別在表的兩端進行。 插入的那一端稱為隊尾,刪除的那一端稱為隊首。佇列的插入操作和刪除操作分別稱為進隊和出隊。 先進先出(First In First Out) 順序佇列要掌握以下操作:
【資料結構】八大排序之快速排序(遞迴和非遞迴方法)
上一博文我們講了氣泡排序,但是由於他的時間複雜度過高為O(n*n),於是在氣泡排序的基礎上今天要說的是快速排序。 本文講述兩個內容: 1.快速排序的三種方法。 2.快速排序的優化 一.什麼是快速排序??? 通過一趟排序將要排序的資料分割成獨立的兩部
【資料結構】單鏈表的實現
單鏈表是線性錶鏈式儲存的一種形式,其中的結點一般含有兩個域,一個是存放資料資訊的info域,另一個是指向該結點後繼結點存放地址的指標next域。一個單鏈表必須要有一個首指標指向連結串列中的第一個結點。 單鏈表要掌握以下幾種操作: 1、建立一個空的單鏈表。 2、輸出單鏈表
【資料結構】迴圈佇列的實現
#include<stdio.h> #include<stdlib.h> #include<string.h> #include<time.h> #define TURE 1 #define FALSE 0 #de
【資料結構】歸併排序
歸併排序的基本思想是:將兩個(或以上)的有序表組成新的有序表。 更實際的意義:可以把一個長度為n的無序序列看成是n個長度為1的有序子序列,首先做兩兩歸併,得到個長度為2的子序列;再做兩兩歸併,...,如此重複,直到最後得到一個長度為n的有序序列。 例:關鍵字序列T=(21
【資料結構】快速排序(遞迴)
概念: 快速排序是Hoare於1962年提出的一種二叉樹結構的交換排序方法。 基本思想為:任取待排序元素序列中的某元素作為基準值,按照該排序碼將待排序集合分割成兩子序列,左子序列中所有元素均小於基準值,右子序列中所有元素均大於基準值,然後最左右子序列重複該過程,直到所有元素
【資料結構】HashTable原理及實現學習總結
有兩個類都提供了一個多種用途的hashTable機制,他們都可以將可以key和value結合起來構成鍵值對通過put(key,value)方法儲存起來,然後通過get(key)方法獲取相對應的value值。一個是前面提到的HashMap,還有一個就是馬上要講解的HashTa
【資料結構】遞迴演算法—漢諾塔
漢諾塔的問題,也是一個經典的遞迴演算法問題。 下面是自己總結的一張整體流程圖。 下面是程式碼,程式碼雖簡單,但理解其內部執行原理很重要。 //=========================
【資料結構】LinkedList原理及實現學習總結
一、LinkedList實現原理概述 LinkedList 和 ArrayList 一樣,都實現了 List 介面,但其內部的資料結構有本質的不同。LinkedList 是基於連結串列實現的(通過名字也能區分開來),所以它的插入和刪除操作比 ArrayList
【資料結構】迭代器實現二叉樹的中序遍歷
迭代器 template<class T,class Ref,class Ptr> struct __TreeIterator { typedef BinTreeNode<T>
【資料結構】---堆排序
1、堆排序的基本思想是將一組待排序的數列,排成一個大根堆(小根堆),從而輸出堆頂最大的元素,依次類推,將剩下的元素排成堆,依次輸出最大元素,得到有序序列。 堆排序的時間複雜度為。 2、堆排序演算法實現: #include <