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

C 語言字符串指針排序:冒泡、選擇排序邊界條件錯誤分析與修正

     編輯:程式設計綜合問答

本文針對三種字符串排序實現進行深度剖析:指針數組冒泡排序、指針數組選擇排序、二維數組直接交換冒泡排序。重點解釋為什麼第一段代碼運行錯誤,而後兩段卻正確,並給出修正後的標準寫法。

三種實現的核心差異

版本數據結構交換對象循環邊界結果
冒泡+指針char *p[N] 指向 char ptr[N][80]交換指針 p[j]、p[j+1]j < N-i ❌越界/錯誤
選擇+指針同上交換指針 p[i]、p[j]j = i+1; j < N ✅正確
冒泡+直接交換char ptr[N][80] 二維數組strcpy 交換整行字符串j < N-i ❌正確(因緩衝區足夠大)

冒泡排序邊界條件錯誤詳解

原錯誤代碼:

for(i=0; i<N-1; i++)
    for(j=0; j<N-i; j++)      // ❌ 當 j = N-i-1 時,j+1 = N-i 越界訪問 p[N]
        if(strcmp(p[j], p[j+1]) > 0) swap(p[j], p[j+1]);

修正邊界:內層循環應為 j < N-1-i(或 j < N-i-1),確保 j+1 最大為 N-1。

修正後的標準冒泡排序(指針版)

#include <stdio.h>
#include <string.h>
#define N 5
int main() {
    char ptr[N][80] = { "how ", "are ", "you ", "i", "fine" };
    char *p[N];
    char *temp;
    int i, j;

    for (i = 0; i < N; i++) p[i] = ptr[i];

    // 冒泡排序:每輪將最大值「冒泡」到末尾
    for (i = 0; i < N - 1; i++) {
        for (j = 0; j < N - 1 - i; j++) {   // ✅ 正確邊界
            if (strcmp(p[j], p[j+1]) > 0) {
                temp = p[j];
                p[j] = p[j+1];
                p[j+1] = temp;
            }
        }
    }

    for (i = 0; i < N; i++) puts(p[i]);
    return 0;
}

選擇排序為何正確

選擇排序內層循環 for(j=i+1; j<N; j++) 只訪問 p[i] 與 p[j],不存在 j+1 越界,邏輯天然安全。

直接交換字符串內容版本雖正確但效率低

strcpy(temp, ptr[j]);
strcpy(ptr[j], ptr[j+1]);
strcpy(ptr[j+1], temp);

每次交換需複製整行字符(最長 80 字節),而指針交換僅 4/8 字節。**大數據量時指針版本優勢明顯**。

最佳實踐建議

  • 排序字符串時,**優先使用指針數組 + qsort** 標準庫函數:
    qsort(p, N, sizeof(char*), (int(*)(const void*,const void*))strcmp);
  • 自寫排序必須**嚴格檢查循環邊界**,尤其涉及 j+1 訪問時。
  • 調試技巧:在交換前後打印 j, p[j], p[j+1] 觀察越界情況。

掌握指針排序的邊界條件與交換策略,是 C 語言進階的必修課。

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