數據結構入門:詳解順序表的實現與操作

目錄

1.線性表

2.順序表

2.1概念與結構

2.2分類

2.2.1靜態順序表

2.2.2動態順序表?

3.動態順序表的實現

3.1.SeqList.h

3.2.SeqList.c

3.2.1初始化

?3.2.2銷毀

3.2.3打印

3.2.4順序表擴容?

3.2.5尾部插入及尾部刪除?

3.2.6頭部插入及頭部刪除?

3.2.7特定位置插入及刪除?

3.2.8查找元素,返回下標?

?4.順序表算法題

1.力扣:移除元素

核心思想

算法步驟

?2.力扣:刪除有序數組的重復項

核心思想

算法步驟

?3.力扣:合并兩個有序數組

核心思想

算法步驟


1.線性表

在講順序表之前,我們首先要介紹一個概念,線性表。

線性表(Linear List)是數據結構中最基礎、最常用的一種結構,它的特點是數據元素之間按線性順序排列,每個元素最多有一個前驅和一個后繼。

線性表有兩種實現方式,其一是順序表,其二是鏈表。以下我們來為他們做一個簡單區分:

順序表(順序存儲)鏈表(鏈式存儲)
實現方式數組存儲元素,內存連續分配結點存儲元素和指針,內存非連續分配
特點
  • 支持隨機訪問(通過下標直接訪問元素,時間復雜度 O(1))。

  • 插入/刪除可能需要移動大量元素(時間復雜度 O(n))。

  • 存儲空間固定(需預先分配,可能浪費或不足)。

  • 插入/刪除高效(時間復雜度 O(1),僅需修改指針)。

  • 不支持隨機訪問(查找需從頭遍歷,時間復雜度 O(n))。

  • 存儲空間動態分配,更靈活。

適用場景元素數量固定、頻繁查詢、少增刪。頻繁增刪、元素數量變化大。

表格內容暫時看不明白沒有關系,這里只是做一個簡介,相信等你看完博客之后會有一個新的體會。

今天我們著重介紹的是順序表,鏈表會放在下一篇博客中精講。


2.順序表

2.1概念與結構

概念:順序表是??段物理地址連續的存儲單元依次存儲數據元素的線性結構,?般情況下采?數組存儲。

順序表和數組的區別??

順序表是數據結構中線性表的一種實現方式,本質是基于數組的封裝,通過數組實現元素的連續存儲,并添加了對數據操作的邏輯(如插入、刪除、擴容等)。

2.2分類

2.2.1靜態順序表

定義與特點

  • 固定容量:在創建時分配固定大小的內存空間,無法動態擴展或收縮

  • 內存分配:通常在編譯階段確定(如全局數組)或在棧上分配(如局部數組),內存管理由系統自動完成。

  • 操作限制:僅支持基本的讀寫操作,插入和刪除需手動移動元素,效率較低。

#define SLDataType int   // 定義順序表元素類型為int(便于后期類型修改)
#define N 7              // 定義順序表容量為7(固定大小)// 靜態順序表結構體定義
typedef struct Seqlist { // 類型重命名為SLSLDataType arr[N];   // 固定大小的數組存儲元素int size;            // 記錄當前有效元素個數(核心狀態標識)
} SL;                    // 類型重命名簡化

2.2.2動態順序表?

?定義與特點

  • 可變容量:支持運行時動態調整容量(擴展或收縮),通過重新分配內存實現。

  • 內存分配:通常在堆上動態分配,由程序邏輯管理(如?malloc?或?new)。

  • 高級操作:封裝了插入、刪除、擴容等復雜邏輯,用戶無需手動處理內存。

// 定義順序表存儲的元素類型為int
// 使用宏定義方便后續修改元素類型(例如改為float或自定義結構體)
#define SLDataType int  // 動態順序表結構體定義
typedef struct Seqlist {SLDataType* arr;   // 指向動態分配數組的指針(存儲元素)int size;          // 當前順序表中有效元素的數量int capacity;      // 當前順序表的總容量
} SL;  // 使用typedef將結構體重命名為SL,簡化代碼

將靜態順序表和動態數據表做一個對比:

特性靜態順序表動態順序表
存儲方式固定大小數組(棧內存/全局區)動態分配數組(堆內存)
容量編譯時確定(#define N 7),不可變運行時動態調整(通過malloc/realloc
內存分配自動分配和釋放(無需手動管理)需手動管理(malloc/free
擴容/縮容不支持,大小固定支持,可動態調整(如capacity不足時擴容)

經過比對,我們發現?

  • 靜態順序表簡單但僵化,適合確定性的小規模數據。

  • 動態順序表復雜但強大,是現代編程語言中動態數組的基礎實現。

本文將以實現動態順序表為主,詳細講述動態順序表的擴容,頭插,尾插,刪除等操作。


3.動態順序表的實現

3.1.SeqList.h

#pragma once#include<stdio.h>
#include<stdlib.h>
#include<assert.h>typedef int SLDataType;// 動態順序表 -- 按需申請
typedef struct SeqList
{SLDataType* arr;int size; // 有效數據個數int capacity; // 空間容量
}SL;//初始化和銷毀
void SLInit(SL* ps);
void SLDestroy(SL* ps);
void SLPrint(SL* ps);//擴容
void SLCheckCapacity(SL* ps);//頭部插?刪除 / 尾部插?刪除
void SLPushBack(SL* ps, SLDataType x);
void SLPopBack(SL* ps);
void SLPushFront(SL* ps, SLDataType x);
void SLPopFront(SL* ps);//指定位置之前插?/刪除數據
void SLInsert(SL* ps, int pos, SLDataType x);
void SLErase(SL* ps, int pos);int SLFind(SL * ps, SLDataType x);

一個動態順序表至少應該能夠實現以上功能,下面我們來逐一實現。

3.2.SeqList.c

3.2.1初始化
void SLInit(SL* ps)
{ps->arr = NULL;ps->capacity = 0;ps->size = 0;
}
?3.2.2銷毀
void SLDestroy(SL* ps)
{if (ps->arr){free(ps->arr);}ps->arr = NULL;ps->capacity = 0;ps->size = 0;
}

注意:這里釋放空間需要判斷指針是否為空,如果是空指針直接釋放會報錯,同時我們要檢查的是ps->arr,并不是ps,需要額外注意,不要釋放ps的空間和將ps置空指針

3.2.3打印
void SLPrint(SL* ps)
{for (int i = 0; i < ps->size; i++){printf("%d ", ps->arr[i]);}printf("\n");
}
3.2.4順序表擴容?
void SLCheckCapacity(SL* ps)
{// 檢查是否需要擴容(當前元素數 == 當前容量)if (ps->capacity == ps->size){// 計算新容量:如果當前容量為0(初始狀態)則設為4,否則擴容2倍int new_capacity = ps->capacity == 0 ? 4 : 2 * (ps->capacity);// 嘗試重新分配內存SLDataType* tem = realloc(ps->arr, new_capacity * sizeof(SLDataType));// 處理內存分配失敗的情況if (tem == NULL){perror("realloc");  // 打印錯誤信息exit(EXIT_FAILURE); // 終止程序(EXIT_FAILURE是標準錯誤退出碼)}// 更新順序表結構ps->arr = tem;           // 指向新分配的內存ps->capacity = new_capacity; // 更新容量值}
}

關鍵點說明:

  1. 擴容時機

    • size == capacity時觸發擴容,這是為了防止下一次插入操作導致溢出

  2. 擴容策略

    • 初始容量設為4(常見設計,避免初期頻繁擴容)

    • 之后每次按2倍擴容(標準庫常用策略,均攤時間復雜度為O(1))

  3. 內存管理

    • 使用realloc而不是malloc,可以保留原有數據

    • 必須檢查返回值是否為NULL(內存分配可能失敗)

  4. 錯誤處理

    • 使用perror輸出錯誤信息(會顯示系統級的錯誤原因)

    • EXIT_FAILURE是標準庫定義的錯誤退出碼(通常值為1)

  5. 安全性

    • 先將realloc結果賦給臨時變量tem,確認成功后再賦給ps->arr

    • 避免直接ps->arr = realloc(...)導致內存泄漏

3.2.5尾部插入及尾部刪除?
/*** @brief 在順序表尾部插入一個元素* @param ps 指向順序表結構的指針(必須非空)* @param x 要插入的元素值*/
void SLPushBack(SL* ps, SLDataType x) {assert(ps);              // 確保順序表指針有效(若ps為NULL則終止程序)SLCheckCapacity(ps);     // 檢查并擴容(若容量不足)ps->arr[ps->size++] = x; // 在尾部插入元素,并更新size
}/*** @brief 刪除順序表尾部元素(邏輯刪除)* @param ps 指向順序表結構的指針(必須非空且arr有效)*/
void SLPopBack(SL* ps) {assert(ps && ps->arr);  // 確保順序表指針和內部數組指針均有效ps->size--;             // 減少size,忽略最后一個元素(邏輯刪除)
}
3.2.6頭部插入及頭部刪除?
/*** @brief 在順序表頭部插入一個元素* @param ps 指向順序表結構的指針(必須非空且內部數組已初始化)* @param x 要插入的元素值* @note 時間復雜度 O(n),需要移動所有元素*/
void SLPushFront(SL* ps, SLDataType x) {// 1. 參數校驗assert(ps && ps->arr);  // 確保順序表指針和內部數組指針有效// 2. 容量檢查(必要時擴容)SLCheckCapacity(ps);    // 檢查并處理容量不足的情況// 3. 移動元素:從后往前逐個后移for (int i = ps->size; i > 0; i--) {ps->arr[i] = ps->arr[i - 1];  // 將元素向后移動一位}// 4. 插入新元素到頭部ps->arr[0] = x;  // 在數組頭部放入新元素// 5. 更新元素計數ps->size++;      // 順序表長度+1
}/*** @brief 刪除順序表頭部元素* @param ps 指向順序表結構的指針(必須非空且順序表不為空)* @note 時間復雜度 O(n),需要移動剩余所有元素*/
void SLPopFront(SL* ps) {// 1. 參數校驗assert(ps && ps->size > 0);  // 確保順序表有效且不為空// 2. 移動元素:從前往后逐個前移for (int i = 0; i < ps->size - 1; i++) {ps->arr[i] = ps->arr[i + 1];  // 將元素向前移動一位}// 3. 更新元素計數ps->size--;  // 順序表長度-1/* 可選:清零最后一個元素位置的值ps->arr[ps->size] = 0;  // 防止臟數據*/
}
3.2.7特定位置插入及刪除?
/*** @brief 在順序表指定位置前插入元素* @param ps 指向順序表結構的指針(必須非空)* @param pos 要插入的位置索引(0 ≤ pos ≤ ps->size)* @param x 要插入的元素值* @note 時間復雜度 O(n),需要移動元素* @note 邊界情況:*       - pos=0:相當于頭部插入*       - pos=size:相當于尾部追加*/
void SLInsert1(SL* ps, int pos, SLDataType x) {assert(ps);  // 確保順序表指針有效assert(pos >= 0 && pos <= ps->size);  // 檢查位置合法性SLCheckCapacity(ps);  // 檢查并擴容(若容量不足)// 從后往前移動元素,騰出pos位置for (int i = ps->size; i > pos; i--) {ps->arr[i] = ps->arr[i - 1];  // 元素后移}ps->arr[pos] = x;  // 在pos位置插入新元素ps->size++;        // 更新元素數量
}/*** @brief 在順序表指定位置后插入元素* @param ps 指向順序表結構的指針(必須非空)* @param pos 參考位置索引(0 ≤ pos < ps->size)* @param x 要插入的元素值* @note 時間復雜度 O(n),需要移動元素* @note 邊界情況:*       - pos=0:在第一個元素后插入*       - pos=size-1:相當于尾部追加*/
void SLInsert2(SL* ps, int pos, SLDataType x) {assert(ps);  // 確保順序表指針有效assert(pos >= 0 && pos < ps->size);  // 檢查位置合法性SLCheckCapacity(ps);  // 檢查并擴容// 從后往前移動元素,騰出pos+1位置for (int i = ps->size; i > pos + 1; i--) {ps->arr[i] = ps->arr[i - 1];  // 元素后移}ps->arr[pos + 1] = x;  // 在pos+1位置插入新元素ps->size++;            // 更新元素數量
}/*** @brief 刪除順序表指定位置的元素* @param ps 指向順序表結構的指針(必須非空且順序表非空)* @param pos 要刪除的位置索引(0 ≤ pos < ps->size)* @note 時間復雜度 O(n),需要移動元素* @note 邊界情況:*       - pos=0:刪除頭部元素*       - pos=size-1:刪除尾部元素*/
void SLErase(SL* ps, SLDataType pos) {assert(ps && ps->size > 0);  // 確保順序表有效且非空assert(pos >= 0 && pos < ps->size);  // 檢查位置合法性// 從pos位置開始,用后續元素覆蓋當前元素for (int i = pos; i < ps->size - 1; i++) {ps->arr[i] = ps->arr[i + 1];  // 元素前移}ps->size--;  // 更新元素數量/* 可選:清除殘留數據(防止臟數據)ps->arr[ps->size] = 0;*/
}
3.2.8查找元素,返回下標?
/*** @brief 在順序表中查找指定元素的位置* @param ps 指向順序表結構的指針(必須非空)* @param x 要查找的元素值* @return 如果找到,返回元素的索引(0 ≤ index < size);*         如果未找到,返回 -1* @note 時間復雜度 O(n),需要遍歷數組*/
int SLFind(SL* ps, SLDataType x) {assert(ps);  // 確保順序表指針有效// 遍歷順序表查找元素for (int i = 0; i < ps->size; i++) {if (ps->arr[i] == x) {return i;  // 找到元素,返回索引}}return -1;  // 未找到元素
}

?4.順序表算法題

1.力扣:移除元素

核心思想

使用?雙指針技巧

  • src(源指針):遍歷原始數組,檢查每個元素。

  • dst(目標指針):記錄非?val?元素的存儲位置。

算法步驟

  1. 初始化?src?和?dst?為 0。

  2. 遍歷數組:

    • 如果?nums[src] == val:跳過該元素(src++)。

    • 如果?nums[src] != val:將其復制到?nums[dst],然后?src++?和?dst++

  3. 最終?dst?的值即為新數組的長度。

代碼:

int removeElement(int* nums, int numsSize, int val) {int src = 0,dst = 0;while(src<numsSize){if(nums[src]==val)src++;else{nums[dst] = nums[src];dst++;src++;}}return dst;
}

?2.力扣:刪除有序數組的重復項

核心思想

使用?雙指針技巧

  • dst(目標指針):記錄唯一元素的存儲位置。

  • src(源指針):遍歷數組,尋找與?dst?不同的元素。

算法步驟

  1. 初始化?dst = 0(第一個元素必定唯一),src = 1

  2. 遍歷數組:

    • 如果?nums[dst] == nums[src]:跳過重復元素(src++)。

    • 如果?nums[dst] != nums[src]:將?nums[src]?復制到?nums[++dst],然后?src++

  3. 最終?dst + 1?即為新數組的長度(因為索引從 0 開始)。

?代碼:

int removeDuplicates(int* nums, int numsSize) {int dst = 0,src = 1;while(src<numsSize){if(nums[dst]==nums[src]){src++;}else{nums[++dst] = nums[src++];}}return dst+1;
}

?3.力扣:合并兩個有序數組

核心思想

使用?逆向雙指針法?從后向前合并,避免覆蓋?nums1?中的未處理元素。

算法步驟

  1. 初始化指針

    • l1 = m - 1:指向?nums1?的最后一個有效元素。

    • l2 = n - 1:指向?nums2?的最后一個元素。

    • l3 = m + n - 1:指向?nums1?的末尾(合并后的位置)。

  2. 逆向遍歷合并

    • 比較?nums1[l1]?和?nums2[l2],將較大的值放入?nums1[l3],并移動對應指針。

    • 重復直到?nums1?或?nums2?遍歷完畢。

  3. 處理剩余元素

    • 如果?nums2?有剩余元素(l2 >= 0),直接復制到?nums1?的前端。

代碼:

void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n) {int l1 = m-1,l2 = n-1,l3 = m+n-1;while(l1>=0 && l2>=0){if(nums1[l1]>nums2[l2]){nums1[l3] = nums1[l1];l3--;l1--;}else{nums1[l3] = nums2[l2];l2--;l3--;}}while(l2>=0){nums1[l3] = nums2[l2];l2--;l3--;}
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/77693.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/77693.shtml
英文地址,請注明出處:http://en.pswp.cn/web/77693.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

LeetCode熱題100--53.最大子數組和--中等

1. 題目 給你一個整數數組 nums &#xff0c;請你找出一個具有最大和的連續子數組&#xff08;子數組最少包含一個元素&#xff09;&#xff0c;返回其最大和。 子數組是數組中的一個連續部分。 示例 1&#xff1a; 輸入&#xff1a;nums [-2,1,-3,4,-1,2,1,-5,4] 輸出&…

python:練習:2

1.題目&#xff1a;統計一篇英文文章中每個單詞出現的次數&#xff0c;并按照出現次數排序輸出。 示例輸入&#xff1a; text "Python is an interpreted, high-level, general-purpose programming language. Created by Guido van Rossum and first released in 1991…

AI Agent 孵化器?開源框架CAMEL

簡介 CAMEL&#xff08;Communicative Agents for Mind Exploration of Large Scale Language Model Society&#xff09;是一個開源框架&#xff0c;大語言模型多智能體框架的先驅者。旨在通過角色扮演和自主協作&#xff0c;探索大語言模型&#xff08;LLM&#xff09;在多智…

關于插值和擬合(數學建模實驗課)

文章目錄 1.總體評價2.具體的課堂題目 1.總體評價 學校可以開設這個數學建模實驗課程&#xff0c;我本來是非常的激動地&#xff0c;但是這個最后的上課方式卻讓我高興不起哦來&#xff0c;因為老師講的這個內容非常的簡單&#xff0c;而且一個上午的數學實驗&#xff0c;基本…

LayerSkip: Enabling Early Exit Inference and Self-Speculative Decoding

TL;DR 2024 年 Meta FAIR 提出了 LayerSkip&#xff0c;這是一種端到端的解決方案&#xff0c;用于加速大語言模型&#xff08;LLMs&#xff09;的推理過程 Paper name LayerSkip: Enabling Early Exit Inference and Self-Speculative Decoding Paper Reading Note Paper…

解決ktransformers v0.3 docker鏡像中 operator torchvision::nms does not exist 問題

問題背景 更新ktransformers docker鏡像到v0.3版本后&#xff08;之前為v0.2.4post1&#xff09;&#xff0c;使用更新前啟動命令無法正確啟動服務&#xff0c;提示以下錯誤&#xff1a; Traceback (most recent call last):File "/workspace/ktransformers/ktransforme…

如何系統學習音視頻

學習音視頻技術涉及多個領域&#xff0c;包括音頻處理、視頻處理、編碼解碼、流媒體傳輸等。 第一階段&#xff1a;基礎知識準備 目標&#xff1a;掌握音視頻學習所需的計算機科學和數學基礎。 計算機基礎 學習計算機網絡基礎&#xff08;TCP/IP、UDP、HTTP、RTSP等協議&#…

TiDB 可觀測性最佳實踐

TiDB 介紹 TiDB&#xff0c;由 PingCAP 公司自主研發的開源分布式關系型數據庫&#xff0c;是一款創新的 HTAP 數據庫產品&#xff0c;它融合了在線事務處理&#xff08;OLTP&#xff09;和在線分析處理&#xff08;OLAP&#xff09;的能力&#xff0c;支持水平擴容和縮容&…

使用FreeRTOS解決單片機串口異步打印

單片機串口異步打印 文章目錄 單片機串口異步打印前言設計思路準備隊列創建完整代碼 總結 前言 &#x1f30a;在單片機開發中串口的異步打印異步打印允許單片機在執行其他任務的同時進行打印操作&#xff0c;無需等待打印完成后再繼續執行后續代碼&#xff0c;避免了在多處調用…

代碼顏色模式python

1. CMYK&#xff08;印刷場景&#xff09; 例子&#xff1a;某出版社設計書籍封面時&#xff0c;使用 Adobe Illustrator 繪制圖案。 紅色封面的 CMYK 值可能為&#xff1a;C0, M100, Y100, K0&#xff08;通過洋紅和黃色油墨混合呈現紅色&#xff09;。印刷前需將設計文件轉…

HarmonyOS NEXT 詩詞元服務項目開發上架全流程實戰(二、元服務與應用APP簽名打包步驟詳解)

在HarmonyOS應用開發過程中&#xff0c;發布應用到應用市場是一個重要的環節。沒經歷過的童鞋&#xff0c;首次對HarmonyOS的應用簽名打包上架可能感覺繁瑣。需要各種秘鑰證書生成和申請&#xff0c;混在一起分不清。其實搞清楚后也就那會事&#xff0c;各個文件都有它存在的作…

【BotSharp框架示例 ——實現聊天機器人,并通過 DeepSeek V3實現 function calling】

BotSharp框架示例 ——實現聊天機器人&#xff0c;并通過 DeepSeek V3實現 function calling 一、一點點感悟二、創建項目1、創建項目2、添加引用3、MyWeatherPlugin項目代碼編寫4、WeatherApiDefaultService項目代碼編寫5、WebAPI MyWeatherAPI 的項目代碼編寫6、data文件夾中…

百度CarLife實現手機車機無縫互聯

百度CarLife是百度推出的智能車聯網解決方案&#xff0c;通過手機與車機互聯技術&#xff0c;為用戶提供安全便捷的車載互聯網服務體驗。 CarLife 實現手機與車機屏幕的無縫互聯&#xff0c;讓應用內容同步至車載系統&#xff0c;減少駕駛過程中操作手機的頻率&#xff0c;提升…

基于STM32的虛線繪制函數改造

改造前&#xff1a; uint16_t DrawLine(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2) { // GUI_DrawLine( x1, y1, x2, y2); // return 1;int16_t deltaX, deltaY;int16_t error, stepErrorLT, stepErrorGE;int16_t stepX, stepY;int16_t steep;int16_t…

Java高頻面試之并發編程-10

hello啊&#xff0c;各位觀眾姥爺們&#xff01;&#xff01;&#xff01;本baby今天來報道了&#xff01;哈哈哈哈哈嗝&#x1f436; 面試官&#xff1a;ThreadLocalMap 怎么解決 Hash 沖突的&#xff1f; ThreadLocalMap 是 ThreadLocal 的核心實現&#xff0c;它采用 開放…

AI應用實戰:Excel表的操作工具

有個小需求是這樣的&#xff0c;需要在一份數據表里&#xff0c;將1000多個客戶的月報數據分別單獨截圖存檔&#xff0c;有客戶需要的時候就要發給客戶&#xff0c;截圖下來的也是以客戶為命名&#xff0c;這樣查找時也比較容易匹配上。 在沒有寫工具之前&#xff0c;以往財務…

使用 DoH 查詢域名 —— 以 core.tantanapp.com 為例的實戰分析

前言 在現代 iOS 應用中&#xff0c;為了確保 DNS 查詢的隱私和完整性&#xff0c;我們可以使用 DoH&#xff08;DNS over HTTPS&#xff09; 來查詢域名信息。 本文將以 https://cloudflare-dns.com/dns-query?namecore.tantanapp.com&typeA 為例&#xff0c;通過 Postm…

Python----卷積神經網絡(卷積為什么能識別圖像)

一、卷積的概念 卷積是一種數學運算&#xff0c;通常用于信號處理和圖像分析。在卷積神經網絡中&#xff0c;卷積操作用于提取輸入數據&#xff08;如圖像&#xff09;中的特征。通過將輸入數據與卷積核&#xff08;濾波器&#xff09;進行卷積運算&#xff0c;CNN能夠識別圖像…

linux FTP服務器搭建

FTP服務器搭建 系統環境&#xff1a;ubuntu 搭建方式&#xff1a;win系統下通過ssh連接ubuntu&#xff0c;搭建FTP服務 一、ssh連接 ssh -p 端口 用戶名IP ssh -p 22 ubuntu192.168.1.109 密碼&#xff1a;ubuntu123456 二、安裝配置FTP服務器 1、安裝 sudo apt install v…

語音合成之十韻律之美:TTS如何模擬語音的節奏和語調

韻律之美&#xff1a;TTS如何模擬語音的節奏和語調 1. 引言&#xff1a;韻律在語音合成中的重要性1.1 追求自然的TTS&#xff1a;超越可懂度1.2 定義韻律&#xff1a;語音的音樂1.3 韻律為何重要&#xff1a;傳遞意義、情感與自然度 2. TTS韻律建模的基礎技術2.1 利用文本&…