首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

C 語言實現基於二叉堆的優先隊列與 const 關鍵字深度解析

     編輯:Java 相關知識

項目背景

本文基於 C 語言實現一個通用的**優先隊列**,底層數據結構採用**二叉堆**,並深度解析 C/C++ 中 const 關鍵字在變量、指針、函數參數、返回值、類成員中的多維用法與陷阱。


第一部分:優先隊列數據結構設計

1. 核心數據結構

// 鍵值對節點
typedef struct KeyValue {
    int key;           // 優先級鍵
    void *value;       // 業務數據指針
} KeyValue;

// 優先隊列結構體
typedef struct PriorityQueue {
    KeyValue **nodes;  // 二叉堆數組 (指針數組)
    int size;          // 當前元素數量
    int capacity;      // 數組容量
    int priority;      // PRIORITY_MAX(1) 或 PRIORITY_MIN(2)
} PriorityQueue;

2. 核心 API 設計

函數功能時間複雜度
priority_queue_new(priority)創建隊列,指定大/小頂堆O(1)
priority_queue_enqueue(pq, kv)入隊 (上浮調整)O(log n)
priority_queue_dequeue(pq)出隊取頂 (下沉調整)O(log n)
priority_queue_top(pq)查看隊首 (不刪除)O(1)
priority_queue_size/empty(pq)狀態查詢O(1)
priority_queue_free(pq, freeValue)銷毀隊列,回調釋放 value 內存O(n)

3. 關鍵算法:上浮與下沉

  • 入隊上浮:新元素放入 nodes[size],size++,當前索引 i = size-1,父節點 parent = (i-1)/2。若當前優先級高於父節點,交換並 i = parent 繼續,直到根或不大於父節點。
  • 出隊下沉:保存 nodes[0] 為返回值,將尾節點 nodes[size-1] 移至根,size--。從根開始,比較左右子節點 left=2*i+1, right=2*i+2,找出優先級最高的子節點 j,若根優先級低於 j,交換並 i=j 繼續,直到葉子或不低於子節點。

4. 動態擴容

static void priority_queue_realloc(PriorityQueue *pq) {
    pq->capacity *= 2;
    pq->nodes = realloc(pq->nodes, sizeof(KeyValue*) * pq->capacity);
}

第二部分:const 關鍵字完全指南

const 核心語義:**「只讀」**,編譯器強制檢查,運行期無開銷,助於優化與防錯。

1. 修飾變量與指針 (核心難點)

口訣:從右向左讀,遇 * 說「指向」,遇 const 說「只讀」。

聲明含義可修改項
const int *p / int const *p指向 常量整數的指針指針 p 本身
int * const p指向整數的 常量指針指向的值 *p
const int * const p指向常量整數的 常量指針無

2. 修飾函數參數

  • void func(const int n):傳值參數無意義 (副本本身可改)。
  • void func(const char *str):承諾不修改字符串內容,可接收字符串字面量。
  • void func(char * const ptr):承諾不修改指針本身 (少用)。
  • void func(const MyClass &obj):引用傳參避免拷貝,且保護對象不被修改 (C++ 核心用法)。

3. 修飾函數返回值

  • const int func():返回值為常量 (內置類型無實際意義)。
  • const char* func():返回指向常量的指針,調用者不可修改內容。
  • char* const func():返回常量指針 (極少見)。

4. 修飾類成員 (C++)

場景語法效果
常量成員變量const int MAX_SIZE;初始化列表賦值,對象生命周期內不可改
常量成員函數void print() const;承諾不修改非 mutable 成員,可被 const 對象調用
const 對象const MyClass obj;只能調用 const 成員函數

5. const vs #define

維度const#define
階段編譯/運行期預處理期 (文本替換)
類型安全有類型檢查無類型,純文本
作用域遵循作用域規則全局文件級
內存分配內存 (可取址)不分配,純展開
調試符號表可見符號表不可見

6. 進階陷阱

  • 指針傳遞:void func(int **p) 不能傳 const int ** (雙重指針 const 轉換規則嚴格)。
  • mutable:允許 const 成員函數修改特定字段 (如緩存、鎖)。
  • 類型轉換:const_cast 移除 const (危險,僅用於對接舊 API)。

完整代碼結構 (pq.h / pq.c / main.c)

代碼採用**基於對象**風格:結構體封裝數據,函數指針作為方法,構造/析構函數管理生命周期,私有函數靜態內聯。編譯命令:gcc pq.c main.c -o pq_test。

總結

二叉堆優先隊列是經典數據結構,C 語言手動管理內存配合 const 防禦性編程,能構建高效、健壯的系統級組件。掌握 const 的「右左讀法」與各層級語義,是 C/C++ 進階的必修課。

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