1. 程式人生 > >【資料結構】各類排序演算法的實現

【資料結構】各類排序演算法的實現

 給出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 <