首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

C 語言冒泡排序邏輯錯誤分析:降序變升序、邊界條件與交換判斷修正

     編輯:程式設計疑難解答

冒泡排序看似簡單,實則暗藏邊界條件、比較方向、交換邏輯三大陷阱。本文針對典型錯誤代碼逐行解析,給出正確的降序/升序實現模板。

原代碼錯誤剖析


void bubblesort(intArr* ia) {
    int i, j, t, n = ia->cur;
    for (i = n; i > 2; i--)           // 錯誤1:外層邊界
        for (j = 1; j                // 錯誤2:內層邊界缺失、缺少大括號
            if (ia->pt[j] > ia->pt[j-1]) { // 錯誤3:> 為降序,註釋稱升序
                t = ia->pt[j-1];
                ia->pt[j-1] = ia->pt[j];
                ia->pt[j] = t;
            }
}

三大核心錯誤

  1. 外層迴圈邊界錯:i > 2 應為 i > 1 (或 i >= 1),否則最後兩個元素不參與比較
  2. 內層迴圈條件缺失:j 後無條件,應為 j < i (0 基址) 或 j <= i (1 基址)
  3. 比較方向與註釋矛盾:> 將大值前移實現降序,註釋卻寫升序

標準冒泡排序模板(0 基址數組)

升序(小→大)


void bubbleSortAsc(int* arr, int n) {
    for (int i = n - 1; i > 0; --i) {        // 趟數:n-1 趟
        bool swapped = false;                 // 優化:提前終止旗標
        for (int j = 0; j < i; ++j) {         // 每趟比較 0 到 i-1
            if (arr[j] > arr[j + 1]) {        // 相鄰逆序則交換
                int t = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = t;
                swapped = true;
            }
        }
        if (!swapped) break;                  // 本趟無交換,已有序
    }
}

降序(大→小)


void bubbleSortDesc(int* arr, int n) {
    for (int i = n - 1; i > 0; --i) {
        bool swapped = false;
        for (int j = 0; j < i; ++j) {
            if (arr[j] < arr[j + 1]) {        // 改為 < 即降序
                int t = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = t;
                swapped = true;
            }
        }
        if (!swapped) break;
    }
}

結構體數組適配版


typedef struct {
    int* pt;      // 數據指針
    int cur;      // 當前長度
} IntArr;

void bubbleSortIntArr(IntArr* ia, bool ascending) {
    for (int i = ia->cur - 1; i > 0; --i) {
        bool swapped = false;
        for (int j = 0; j < i; ++j) {
            bool needSwap = ascending ? 
                (ia->pt[j] > ia->pt[j + 1]) : 
                (ia->pt[j] < ia->pt[j + 1]);
            if (needSwap) {
                int t = ia->pt[j];
                ia->pt[j] = ia->pt[j + 1];
                ia->pt[j + 1] = t;
                swapped = true;
            }
        }
        if (!swapped) break;
    }
}

複雜度與優化總結

版本最好情況最壞情況平均情況空間穩定性
基本冒泡O(n²)O(n²)O(n²)O(1)穩定
帶旗標優化O(n)O(n²)O(n²)O(1)穩定
雞尾酒排序O(n)O(n²)O(n²)O(1)穩定

核心口訣:外層控制趟數 (n-1),內層控制比較範圍 (遞減),相鄰比較逆序交換,旗標優化提前退出。掌握此模板,排序不再出錯。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved