八大排序之交換排序

冒泡排序:顧名思義,即每趟排序通過對相鄰兩個元素比較,越大的元素會因交換“浮”到數組的頂端處。
算法思想:對於一組數據,依次將兩個相鄰元素比較,若前者大於後者元素,則將兩者位置交換,直到最後的待排序元素位置。重複進行上述操作,最後數組完全有序。
排序過程如圖所示:
八大排序之交換排序

具體代碼如下:
 C++ Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#incude

void BubbleSort(int arr[], int len)
{
    
for(int i = 0; i < len - 1; i++)
    {
        
bool flag = false;   //設置標誌
        
for(int j = 0; j < len - i - 1; j++)
        {
            
if(arr[j] < arr[j + 1])
            {
                
int tmp = arr[j + 1];
                arr[j + 
1] = arr[j];
                arr[j] = tmp;
                flag = 
true;
            }
        }

        
if(!flag == true)//如果條件爲真,表明待排序數列已有序,直接跳出循環!
        {
            
break;
        }
    }
}

int main()
{
    
int a[] = {32148765109};
    
int len = sizeof(a) / sizeof(a[0]);
    BubbleSort(a, len);
    
for(int i = 0; i < len; i++)
    {
        printf(
"%d  ", a[i]);
    }
}
注:此段代碼實現了冒泡排序算法並進行了優化,我們設置一個flag標誌,當內循環不執行了,即falg等於false時,break跳出外層循環,使排序躺數可能減少。

快速排序:通過一趟排序將一組數據分成兩個獨立的部分,一部分數據比另一部分都小,然後用這個操作將兩個部分分別進行排序,整個排序過程可以遞歸進行,最後全部元素成爲有序序列。
排序過程如圖所示:
八大排序之交換排序

遞歸實現代碼如下:
 C++ Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#include
#include
#include
void Swap(int arr[], int a1, int a2)
{
    
int tmp = arr[a1];
    arr[a1] = arr[a2];
    arr[a2] = tmp;
}

void Gather(int arr[], int low, int high, int pos, int *left, int *right)
{
    
if(low < high)
    {
        
int count = pos-1;
        
for(int i = pos-1; i >= low; i--)
        {
            
if(arr[i] == arr[pos])
            {
                Swap(arr, i, count);
                count--;
            }
        }
        *left = count;
        
int num = pos+1;
        
for(int j = pos+1; j <= high; j++)
        {
            
if(arr[j] == arr[pos])
            {
                Swap(arr, j, num);
                num++;
            }
        }
        *right = num;
    }
}
int Partion(int arr[], int low, int high) //具體分成一部分比另一部分大的排序
{
    
int tmp = arr[low];
    
while(low < high)
    {
        
while(low<=arr[high]) high--;
        arr[low] = arr[high];
        
while(low=arr[low]) low++;
        arr[high] = arr[low];
    }
    arr[low] = tmp;
    
return low;
}

void TakeSecondMaxnum(int arr[], int low, int mid, int high)//三分取中法
{
    
if(arr[mid] < arr[high])
    {
        Swap(arr, mid, high);
    }
    
if(arr[low] < arr[high])
    {
        Swap(arr, low, high);
    }
    
if(arr[low] < arr[mid])
    {
        Swap(arr, low, mid);
    }
}

void InsertSort(int arr[], int  low, int high)//優化一數據量小時,不適宜使用快排,而用插入排序更好
{
    
int i, j;
    
for (i = 2; i < high-low+1; ++i)
    {
        arr[
0] = arr[i];
        
for (j = i - 1; arr[j] > arr[0]; --j)
        {
            arr[j + 
1] = arr[j];
        }   
        arr[j + 
1] = arr[0];
    }
}
void Sort(int arr[], int low, int high)
{
            
if(low < high)
            {
                Swap(arr, low, rand()%(high-low)+low); 
// 優化二,在最壞情況全部有序時交換基準點
            TakeSecondMaxnum(arr, low, (high-low)/2+low, high);//優化三,基準點選取“中數”
            int pos = Partion(arr, low, high);
            
int left = pos-1;
            
int right = pos+1;
            Gather(arr, low, high, pos, &left, &right);
//優化四,聚集與基準點相同的元素,這些元素不參加之後排序
            Sort(arr, low, left);
            Sort(arr, right, high); 
           } 
}
void QuickSort(int arr[], int len)
{
    Sort(arr, 
0, len-1);
}

int main()
{
    
int a[] = {2,3,1,6,5,4,9,8,7,0,21,34,32,27,87,56,43,48,76,29,55};
    
int len = sizeof(a)/sizeof(a[0]);
    QuickSort(a, len);
    
    
for(int i = 0; i < len; i++)
    {
        printf(
"%d ",a[i]);
    }
    printf(
"\n");
}

發佈了35 篇原創文章 · 獲贊 48 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章