1. 程式人生 > 其它 >2021-2-4語法基礎一陣列II

2021-2-4語法基礎一陣列II

技術標籤:課堂筆記

站立遊戲

int a[10010]; //a[i] = 0, 就是編號為i的人的狀態為站著;否則就是坐著

投票統計

int v[11]; //v[i] = j 表示的編號為i的歌手的得票數為j

計數排序(桶排序)

計數排序是一種不基於比較的排序演算法,使用陣列a[]來記錄每個待排序的數的出現次數,遍歷每個數x,將x輸出a[x]。

int a[1010];
for(int i = 1; i <= n; i ++)
{
	int x;
	cin >> x;
	a[x] ++;
}
for(int i = 0; i <= 1000; i ++)
{
	for(int j =
1; j <= a[i]; j ++) cout << i << " "; }
  • 不能對小數或者負數進行排序
  • 如果待排序的數的範圍不確定或者太大

氣泡排序

演算法思想
如果有n個數從小到大排序,經過n-1輪冒泡就完成排序。

  • 在每一輪冒泡中:
    • 從第一個數開始直到n-i,比較相鄰兩個數,如果是逆序
      • 交換這兩數

程式碼實現

/*
156 163 178.6 198 123
經過n-1輪冒泡:
1:156 163 178.6 123 198
2:156 163 123 178.6 198
3:156 123 163 178.6 198
4:123 156 163 178.6 198
*/
#include <iostream> using namespace std; double a[30010]; int main() { //輸入n個數,儲存到陣列中 int n; cin >> n; for(int i = 1; i <= n; i ++) cin >> a[i]; //氣泡排序,一共n-1輪操作 for(int i = 1; i <= n - 1; i ++) { int flag = 0; //每一輪都會沉底一個數,第i輪就會沉底i個數 for(int j = 1; j <= n -
i; j ++) { //如果是逆序關係 if(a[j] > a[j + 1]) { flag = 1; //交換a[j]和a[j + 1] double t = a[j]; a[j] = a[j + 1]; a[j + 1] = t; } } if(flag == 0) break; } for(int i = 1; i <= n; i ++) cout << a[i] << " "; return 0; }

時間效率分析

  • 普通計算機一秒鐘最多執行 1 0 8 10^8 108條指令
  • 當 i = 1時,第二層迴圈執行 n - 1次
  • 當 i = 2時,第二層迴圈執行 n - 2次
  • 當 i = 3時,第二層迴圈執行 n - 3次
  • 當 i = n-1時,第二層迴圈執行 1 次
    s u m = ( n − 1 ) + ( n − 2 ) + ( n − 3 ) + . . . + 1 = ( ( n − 1 ) + 1 ) × ( n − 1 ) 2 = n 2 2 − n 2 sum = (n - 1) + (n - 2) + (n - 3) + ... + 1=\frac{((n - 1) + 1) \times (n - 1)}{2}=\frac{n^2}{2} - \frac{n}{2} sum=(n1)+(n2)+(n3)+...+1=2((n1)+1)×(n1)=2n22n
    當n=30000時, 4.5 × 1 0 8 4.5\times10^8 4.5×108

演算法的時間複雜
是衡量演算法時間效率的工具,本質上是演算法中指令的執行次數的界限

  • 只考慮高階項,不考慮低階項
  • 不考慮高階想的常係數

氣泡排序的時間複雜度 O ( n 2 ) O(n^2) O(n2)

插入排序

  • 從第2個數開始,直到最後一個數結束,如果當前位置是i的話:
    • 讓a[i]和前面的數比較,如果是逆序換就交換,直到不是逆序關係停止
/*
156 163 178.6 198 123
從第2個數開始
1:156 163 178.6 123 198
2:156 163 123 178.6 198
3:156 123 163 178.6 198
4:123 156 163 178.6 198
*/
#include <iostream>
using namespace std;
double a[30010];
int main()
{
  //輸入n個數,儲存到陣列中
  int n;
  cin >> n;
  for(int i = 1; i <= n; i ++) cin >> a[i];
  //插入排序,從第2個數開始
  for(int i = 2; i <= n; i ++)
  {
      //跟前面的數進行比較,如果是逆序則交換,否則停止迴圈
      for(int j = i; j > 1 && a[j] < a[j - 1]; j --)
      {
         //交換兩個變數
         swap(a[j], a[j - 1]);
      }      
  }  
  for(int i = 1; i <= n; i ++)
    cout << a[i] << " "; 
  
  return 0;  
}

效率比較

排序演算法最壞情況最好情況平均情況
氣泡排序 O ( n 2 ) O(n^2) O(n2) O ( n ) O(n) O(n) O ( n 2 ) O(n^2) O(n2)
插入排序 O ( n 2 ) O(n^2) O(n2) O ( n ) O(n) O(n) O ( n 2 ) O(n^2) O(n2),實際執行遠好於 O ( n 2 ) O(n^2) O(n2)