單向鏈結串列 Singly Linked Lists.

Slides:



Advertisements
Similar presentations
第10章 结构体与链表 本章要点: 结构体类型与结构体变量的定义 结构体变量的引用与初始化 结构体数组 链表处理 共用体类型和枚举类型
Advertisements

第7章 樹與二元樹 (Trees and Binary Trees)
“八皇后”问题 崔萌萌 吕金华.
第6章 二叉树和树 前面的章节主要讨论的是线性结构,二叉树和树属于非线性的结构。遍历非线性结构比线性结构要麻烦。
数据结构概论 第2章 线性表 董黎刚 浙江工商大学信电学院
第三章 鏈結串列 Linked List.
计算机硕士专业基础—C语言 赵海英
第二章 线性表 1 线性表的逻辑结构及其基本操作 2 线性表的顺序存储结构 3 线性表的链式存储结构 4 静态链表 5 应用实例.
第二章 线性表.
第2章 线性表 2.1 线性表的概念及运算 2.2 线性表的顺序存储 2.3 线性表的链式存储 2.4 一元多项式的表示及相加.
資料結構與C++程式設計進階 資料結構概論 講師:林業峻 CSIE, NTU 6/ 7, 2010.
Linked List(串列) Why Linked List? Pointer Dynamic Allocation
第4章 鏈結串列(Linked Lists) 4-1 動態記憶體配置-(6) 4-2 鏈結串列的基礎-(7)
Linked List Operations
第3章 栈和队列 3.1 栈 3.2 队列 3.3 应用.
第2章 线性表 线性结构 是一个数据元素的有序集合。.
第6章 佇列(Queues) 6-1 佇列的基礎 6-2 佇列的表示法 6-3 環狀佇列 6-4 雙佇列.
第7章 结构体、联合体和枚举类型 本章导读 本章主要知识点 《 C语言程序设计》 (Visual C++ 6.0环境)
C程序设计 第9章 自定义数据类型 主讲教师: 鲁 萍 西安建筑科技大学 理学院.
程式設計 博碩文化出版發行.
struct 可以在同一個名稱下擁有多種資料型態。使用struct能讓資料的存取和處理更為靈活。
第11章 查找 主要知识点 查找的基本概念 静态查找表 动态查找表 哈希表.
佇列 (Queue).
資料結構 第5章 佇列.
第8章 圖形結構(Graphs) 8-1 圖形的基本觀念 8-2 圖形的表示法 8-3 圖形的走訪 8-4 擴張樹
親愛的老師您好 感謝您選用本書作為授課教材,博碩文化準備本書精選簡報檔,特別摘錄重點提供給您授課專用。 說明: 博碩文化:
親愛的老師您好 感謝您選用本書作為授課教材,博碩文化準備本書精選簡報檔,特別摘錄重點提供給您授課專用。 說明: 博碩文化:
补充内容 结构体 概述 定义结构体类型和定义结构体变量 结构体变量的引用 结构体变量的初始化 指针与结构体 用typedef定义类型的别名.
编译原理与技术 类型检查 2018/11/21 《编译原理与技术》-类型检查.
结构体和共用体 2 梁春燕 华电信息管理教研室.
C++语言程序设计 C++语言程序设计 第六章 指针和引用 第十一组 C++语言程序设计.
·线性表的定义及ADT ·线性表的顺序存储结构 ·线性表的链接存储结构 · 单向循环链表 · 双链表、双向循环链表 · 一元多项式的加法
第12章 樹狀搜尋結構 (Search Trees)
第9章 自訂資料型態 – 結構 9-1 結構資料型態 9-2 結構陣列 9-3 指標與結構 9-4 動態記憶體配置 9-5 聯合資料型態
第十五章 Linked List, Stack and Queue
Ch.3 栈和队列 黄刘生 中国科学技术大学计算机系 国家高性能计算中心(合肥)
程式設計 博碩文化出版發行.
(Circular Linked Lists)
第2章 线性表 线性表抽象数据类型 顺序表 主要知识点 单链表 循环单链表 循环双向链表 静态链表 设计举例.
第十章 C高级程序应用—链表* 10.1链表的基本概念 10.2单向链表 10.3双向链表 10.4应用举例.
第5章 堆疊(Stacks) 5-1 堆疊的基礎 5-2 堆疊的表示法 5-3 堆疊的應用 - 運算式的計算與轉換
第5章 堆疊(Stacks) 5-1 堆疊的基礎 5-2 堆疊的表示法 5-3 堆疊的應用 - 運算式的計算與轉換
第3章 堆栈和队列 堆栈 堆栈应用 队列 队列应用 优先级队列 主要知识点.
第三章 栈与队列 £3.1 栈 £3.3 队列 £3.2 栈的应用举例 £3.1.1 栈的定义 £3.1.2 栈的顺序存储结构
第三章 栈和队列.
第二章 线性表.
第 六 章 鏈結串列(Link List) 課程名稱:資料結構 授課老師:________ 2019/1/2.
資料結構與C++程式設計進階 堆疊與佇列(Stack & Queue) 講師:林業峻 CSIE, NTU 6/ 21, 2010.
五、链 表 1、单链表 2、双向链表 3、链表应用.
陈海明 副教授 信息学院 计算机系 电子信息类非计算机专业选修课 程序设计实践 陈海明 副教授 信息学院 计算机系
第三章 栈和队列.
第三章 链表 单链表 (Singly Linked List) 循环链表 (Circular List) 多项式及其相加
王玲 第 2 章 线性表 王玲 2019/2/25.
二叉树的遍历.
3.1 线性表及逻辑结构 3.2 线性表的顺序存储 3.3 线性表的链式存储 3.4 链式存储结构的应用
自我參考結構 (self-reference – 1)
第三章 链表 单链表 循环链表 多项式及其相加 双向链表 稀疏矩阵.
7.1 广义表的概念 广义表是n(n≥0)个数据元素组成的序列,其中每个数据元素或是单个数据元素(简称原子),或仍然是一个广义表 。
第五章 递归与广义表 递归的概念 递归过程与递归工作栈 递归与回溯 广义表.
資料結構與C++程式設計進階 實作練習 講師:林業峻 CSIE, NTU 6/ 24, 2010.
Linked Lists Prof. Michael Tsai 2013/3/12.
第7章 樹與二元樹(Trees and Binary Trees)
本教學投影片係屬教科書著作之延伸,亦受著作權法之保護。
第三章 数据抽象.
第二章 线性表.
<编程达人入门课程> 本节内容 为什么要使用变量? 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ:
第4章 鏈結串列(Linked Lists) 4-1 動態記憶體配置-(6) 4-2 鏈結串列的基礎-(7)
Chapter 2 Entity-Relationship Model
第六章 复合数据类型 指针的声明与使用 数组的声明与使用 指针与数组的相互引用 字符串及相关库函数 new与delete
题目详细要求、参考资料及更新发布于: 第二周 链表与指针 题目详细要求、参考资料及更新发布于:
Presentation transcript:

單向鏈結串列 Singly Linked Lists

定義及表示法 節點包含資料(data)及鏈結(link)兩個欄位。 其資料結構表示,如下圖所示 head:指向串列前端之指標 tail:指向串列尾端之指標

鏈結串列透過儲存元素在記憶體之位址為指標(Pointer)或鏈結(Link)取得下一個節點。故 節點=資料+指標鏈結 假設有一節點結構如下圖所示:

一個指標變數head當作鏈結串列之起始指標,其宣告如下: 則其節點結構可定義如下: typedef struct node { /*以結構體表示節點*/ int data; /*data儲存節點資料項目*/ struct node *next; } NODE; /*next儲存下一個節點位址*/ /*NODE表新定義之節點結構資料型態*/ 一個指標變數head當作鏈結串列之起始指標,其宣告如下: NODE *head; /*head為一個指標,指向鏈結串列之起始節點*/

基本運作及圖解

單向鏈結串列的釋放 當使用malloc配置了記憶體之後,記憶體會一直存在直到程式結束,所以當不使用時必須釋放,釋放的方法為free(變數名稱);請務必記得釋放記憶體,雖然不會發生錯誤訊息,可是會一直在記憶體中,導致記憶體的浪費。

單向鏈結串列插入 如果打算在鏈結中加入一個新的節點,可以使用以下的方法,比方說有一個鏈結串列如下: number 1 2 3 4 5 6 7 8 9 10 name Peter1 Peter2 Peter3 Peter4 Peter5 Peter6 Peter7 Peter8 Peter9 Peter10 next (指標) 指向2號節點 指向3號節點 指向4號節點 指向6號節點 指向7號節點 指向8號節點 指向9號節點 指向10號節點 NULL

現在若想要加入一個11號的Mary節點,加在peter5節點和peter6節點之間,則先新增一個11號的Mary節點: number 1 2 3 4 5 6 7 8 9 10 11 name Peter1 Peter2 Peter3 Peter4 Peter5 Peter6 Peter7 Peter8 Peter9 Peter10 Mary next (指標) 指向2號節點 指向3號節點 指向4號節點 指向6號節點 指向7號節點 指向8號節點 指向9號節點 指向10號節點 NULL 再把串列改成以下這樣就行了: 5號Peter5節點的next指向11號節點。 接著把11號的Mary節點的next指向6號的peter6節點就可以了。 number 1 2 3 4 5 6 7 8 9 10 11 name Peter1 Peter2 Peter3 Peter4 Peter5 Peter6 Peter7 Peter8 Peter9 Peter10 Mary next (指標) 指向2號節點 指向3號節點 指向4號節點 指向6號節點 指11號節點 指向7號節點 指向8號節點 指向9號節點 指向10號節點 NULL 為了要完成以上的方法,必須建立一些變數儲存資料,以這一個範例為例需要2個指標: 指向Mary節點的指標New 指向Peter5節點的指標Ptr

單向鏈結串列刪除 如果打算在鏈結中刪除節點,可以使用以下的方法: 比方說有一個鏈結串列如下: number 1 2 3 4 5 6 7 8 9 10 name Peter1 Peter2 Peter3 Peter4 Peter5 Peter6 Peter7 Peter8 Peter9 Peter10 next (指標) 指向2號節點 指向3號節點 指向4號節點 指向5號節點 指向6號節點 指向7號節點 指向8號節點 指向9號節點 指向10號節點 NULL

若要刪除5號Peter5節點,只需改了2個地方,4號Peter4節點的next指向6號的Peter6: number 1 2 3 4 5 6 7 8 9 10 name Peter1 Peter2 Peter3 Peter4 Peter5 Peter6 Peter7 Peter8 Peter9 Peter10 next (指標) 指向2號節點 指向3號節點 指向4號節點 指向6號節點 指向7號節點 指向8號節點 指向9號節點 指向10號節點 NULL 接著把5號Peter5節點釋放掉,使用Free: number 1 2 3 4 6 7 8 9 10 name Peter1 Peter2 Peter3 Peter4 Peter6 Peter7 Peter8 Peter9 Peter10 next (指標) 指向2號節點 指向3號節點 指向4號節點 指向6號節點 指向7號節點 指向8號節點 指向9號節點 指向10號節點 NULL

單向鏈結串列的反轉 如果鏈結串列如下: 改成: number 1 2 3 4 5 6 7 8 9 name Peter1 Peter2 next (指標) 指向2號節點 指向3號節點 指向4號節點 指向5號節點 指向6號節點 指向7號節點 指向8號節點 指向9號節點 NULL 改成: number 1 2 3 4 5 6 7 8 9 name Peter1 Peter2 Peter3 Peter4 Peter5 Peter6 Peter7 Peter8 Peter9 next (指標) NULL 指向1號節點 指向2號節點 指向3號節點 指向4號節點 指向5號節點 指向6號節點 指向7號節點 指向8號節點

我們先使用1,2,3號節點的位置 把1號節點的next設為Null 再把2號的next指向1號節點 接著使用2,3,4號節點 再把3號的next指向2號節點 接著使用3,4,5號節點 再把4號的next指向3號節點, 接著使用4,5,6號節點,................... 接著使用7,8,9號節點 將8號節點的next指向7號節點 發現9號節點next是NULL,跳出迴圈 把9號節點的next指向8號 把head(頭指標)指向9號節點即可

每一次迴圈次需要使用3個節點,把第2個節點的next指向第1個節點, 下一次的第一個節點是這一次的第二個節點 下一次的第二個節點是這一次的第三個節點 下一次的第三個節點是這一次的第三個節點的next

基本運算的演算法與程式

產生新節點 C語言程式 NODE *getnode (void) /* 此函數產生一個新節點*/ { NODE *p; p = (NODE *) malloc(sizeof(NODE)); /* malloc會動態地配置大小為sizeof 的記憶體*/ /* sizeof會傳回一個型態為NODE之值*/ if ( p == NULL) printf (“記憶體不足”); exit(1); } return(p);

歸還一個節點 C語言程式 void *freenode(NODE*p) /*此函數將節點還給記憶體*/ { free(p); }

尋找一個節點 C語言程式 NODE search_node (NODE *p, int num ) /*自節點p之後尋找一個節點其data項目為 search_data之值*/ {   NODE *q; q = p->next;   /*q指向節點p之後第一個節點*/ while( q!= NULL && q->data != num) q = q->next; /*q改指向下一個節點*/  return(q); }

鍵結串列的節點走訪 C語言程式 NODE find_node(NODE *head, int num) { NODE *ptr; ptr = head; /*指向串列起始*/ while ( ptr != NULL ) /*走訪串列*/ { if ( ptr->num == num ) /*找尋data*/ return (ptr); ptr = ptr->next; } /*指向下一節點*/ }

計算鏈結串列之長度 C語言程式 int length (NODE *p ) /*此函數計算節點p之後之長度*/ { int num=0; NODE *q = p->next; While (q != NULL) { num ++; q = q->next; } return(num); }

節點之插入 由鏈結串列加入一個節點 一個節點之插入有三種情況: 圖解 節點加於第一個節點之前 節點加於最後一個節點之後 加於節點中間任何一個位置 圖解

節點加於第一個節點之前 節點加於最後一個節點之後 加於節點中間任何一個位置

虛擬碼 NODE *insert_node ( NODE *head, NODE *ptr, int value) { 配置記憶體給new; if (ptr is NULL) 插入第一個節點; else if ( ptr->next = = NULL ) 插入最後一個節點; 插入成為中間節點; return (head); }

C語言程式 /*鍵結串列的節點插入*/ NODE *insert_node ( NODE *head, NODE *ptr, int value) { NODE *new; /*新節點指標變數*/ new = getnode(); /*(1)建立新節點,取得一個可用節點*/ new->num = value; /* (2) 建立節點內容*/ new->next = NULL; /* 設定指標初值*/ if ( ptr = = NULL ) /*指標ptr是否是NULL */

{ //第一種情況: 插入第一個節點 new->next = head; /*新節點成為串列開始*/ head = new; } else if ( ptr->next = = NULL ) /*是否是串列結束*/ //第二種情況: 插入最後一個節點 ptr->next = new; /*最後指向新節點*/

else { //第三種情況: 插入成為中間節點 /* (3)新節點指向下一節點*/ new->next = ptr->next; /* (4)節點ptr指向新節點*/ ptr->next = new; } return (head);

刪除節點 由鏈結串列中刪除一個節點: 一個節點之刪除有三種情況: 刪除第一個節點 刪除最後一個節點 加於節點中間任何一個位置 圖解:

刪除第一個節點 刪除最後一個節點

加於節點中間任何一個位置

虛擬碼 NODE *delete_node(NODE *head, NODE *ptr) { NODE *previous; /*指向前一節點*/ if ( ptr = = head ) /*是否是串列開始*/ 刪除第一個節點 else if ( ptr->next = = NULL ) 刪除最後一個節點 刪除中間節點 freenode(ptr); /*此函數將節點歸還給記憶體*/ return(head); }

C語言程式 //鍵結串列的節點刪除 NODE *delete_node(NODE *head, NODE *ptr) { NODE *previous; /*指向前一節點*/ if ( ptr == head ) /*是否是串列開始*/

/* 第一種情況: 刪除第一個節點 */ { head = head->next; return(head); /*reset 起始節點指標*/ } else previous = head; while ( previous->next != ptr ) /*找節點ptr的前節點*/ previous = previous->next; if ( ptr->next == NULL ) /*是否是串列結束*/

//第二種情況: 刪除最後一個節點 previous->next = NULL; /*最後一個節點*/ else //第三種情況: 刪除中間節點 previous->next = ptr->next; /*圖(3)之步驟(1)*/ } freenode(ptr); /*此函數將節點歸還給記憶體*/ return(head);

範例:多項式的相加 多項式相加可以利用鏈結串列來完成。多項式以鏈結串列來表示的話,其資料結構如下: 其中COEF表示變數的係數 EXP LINK 其中COEF表示變數的係數 EXP表示變數的指數 LINK為指到下一節點的指標

假設有一多項式 以鏈結串列表示如下:

若以單向鏈結串列方式呈現 則其C語言程式如下: 假設兩個多項式 與 相加 若以單向鏈結串列方式呈現 則其C語言程式如下: void poly_add(struct node *eq_hl, struct node *eq_h2, struct node *ans_h, struct node *ptr) { struct poly *this_nl, *this_n2, *prev; this_n1 = eq_h1; this_n2 = eq_h2; prev = NULL;

while(this_n1 != NULL || this_n2 != NULL) { /*當兩個多項式皆相加完則結束*/ ptr = (struct poly*) malloc(sizeof(struct poly)); ptr ->next = NULL; //第一個多項式指數大於第二個多項式 if (this_n1 != NULL&& (this_n2 == NULL | | this_n1->exp > this_n2 ->exp)) { ptr->coef = this_n1->coef; ptr->exp = this_n1->exp; this_n1 = this_n1->next; }

//第一個多項式指數大於第二個多項式 else { if (this_n1 != NULL&& (this_n2 == NULL | | this_n1->exp < this_n2 ->exp)) ptr->coef = this_n2->coef; ptr->exp = this_n2->exp; this_n2 = this_n2->next; }

//兩個多項式指數相等,進行相加 else { ptr->coef = this_n1->coef; ptr->exp = this_n1->exp; this_n1 = this_n1->next; ptr->coef = this_n1->coef; + this_n2->coef; if (this_n1 != NULL) this_n1 = this_n1->next; if (this_n1 != NULL) this_n2 = this_n2->next; } if (ptr->coef != 0) if (ans_h = = NULL) ans_h = ptr; else prev -> next = ptr; prev = ptr; else free (ptr);