最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C語言超詳細(xì)講解線性表

 更新時間:2022年07月02日 11:12:34   作者:剛?cè)腴T的小仙女  
線性表,數(shù)據(jù)結(jié)構(gòu)中最簡單的一種存儲結(jié)構(gòu),專門用于存儲邏輯關(guān)系為"一對一"的數(shù)據(jù)。線性表是基于數(shù)據(jù)在實際物理空間中的存儲狀態(tài),又可細(xì)分為順序表(順序存儲結(jié)構(gòu))和鏈表

1. 順序表

順序表是指用一段連續(xù)的地址,依次存放數(shù)據(jù)元素的線性數(shù)據(jù)結(jié)構(gòu)。此種存儲方式使得順序表的物理結(jié)構(gòu)與邏輯結(jié)構(gòu)都是連續(xù)的。

與數(shù)組的區(qū)別:函數(shù)中的數(shù)組被存放在棧段中,而棧段有系統(tǒng)限制的大?。墒褂胾limit -s查看系統(tǒng)限制的大小,單位為KB),因此順序表往往使用在堆段中操作管理動態(tài)數(shù)組的方式實現(xiàn)。

1.1 管理結(jié)點

在順序表中,管理節(jié)點內(nèi)部一般存放:數(shù)據(jù)域地址(*data)、**總?cè)萘?size)以及當(dāng)前數(shù)據(jù)量(len)**等等。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct Vector {
	//數(shù)據(jù)域 
	int *data;
	//總?cè)萘?
	int size;
	//當(dāng)前元素個數(shù) 或 指向末尾元素的后一位
	int len;
} Vector; 
//初始化
Vector *initVector(int size){
	Vector *v = (Vector *) malloc(sizeof(Vertor));
	v->data = (int *) malloc(sizeof(int) * size);
	v->len = 0;
	v->size = size;
	return v; 
} 
//釋放
void freeVector(Vector *v){
	if(!v) return;
	free(v->data);
	free(v);
}
int main(){
	//初始化size為10的線性表
	Vector *v = initVector(10)
	return 0;
}

1.2 順序表的插入

//插入 
//將 v->data[idx] 處變成 val 
void insert(Vector *v, int idx, int val){
	//判斷 v 是否為空 返回 
	if(!v) return; 
	//判斷 idx 是否合法 
	if(idx > v->len || idx < 0) return ;
	//判斷 v 的容量是否已滿
	if(v->len == v->size) return ; 
	//維護(hù)順序表的特性  將 idx 及之后的元素后移 
	for(int i = v->len; i > idx ;i++){
		v->data[i] = v->data[i - 1];
	}
	//在 idx 處插入數(shù)據(jù) 
	v->data[i] = val;
	//更新當(dāng)前元素個數(shù) 
	v->len++; 
} 

1.3 順序表的刪除

//刪除
//將 v->data[idx] 刪除 
void delete(Vector *v, int idx){
	if(!v) return ;
	if(idx >= v->len || idx < 0) return ;
	// idx 之后的元素前移
	for(int i = idx; i < v->len-1; i++){
		v->data[i] = v->data[i + 1];
	}
	v->len--;
}

1.4 順序表的擴(kuò)容

擴(kuò)容:新創(chuàng)建 原size * 2 的空間,然后將原數(shù)據(jù)從原空間遷移到新空間

//倍增法擴(kuò)容 size -> size + exsize
int expand(Vector *v){
	//擴(kuò)容為 size + exSize 
	int exSize = v->size;
	int *tmp;
	while(exSize){
		//嘗試向內(nèi)存申請空間 
		tmp = (int *) realloc(v->data, sizeof(int) * (v->size + exSize));
		//申請成功 
		if(tmp) break;
		//申請不成功 exSize/2 繼續(xù)申請 
		exSize >>= 1; 
	}
	//徹底失敗 未申請到空間 
	if(!tmp) return 0;
	//擴(kuò)容成功
	v->data = tmp; 
	v->size += exSize;
	return 1;
}
//插入 
//將 v->data[idx] 處變成 val 
void insert(Vector *v, int idx, int val){
	...
	if(v->len == v->size) {
		//嘗試擴(kuò)容 擴(kuò)容成功為 1 失敗為 0 
		if(!expand(v)) return; 
	} 
	...
} 

2. 鏈表

2.1 定義

鏈表是一種物理結(jié)構(gòu)不連續(xù),但可以依靠結(jié)點中的指針實現(xiàn)邏輯結(jié)構(gòu)連續(xù)的線性數(shù)據(jù)結(jié)構(gòu)。

構(gòu)成鏈表的數(shù)據(jù)元素被稱為“結(jié)點”,節(jié)點內(nèi)部存放數(shù)據(jù)與指向下一個結(jié)點的指針。

//定義結(jié)點 
typedef struct Node{
	int val;
	struct Node *next;
} Node; 
//結(jié)點初始化 
Node *initNode(int val){
	Node *node = (Node *) malloc(sizeof(Node));
	node->val = val;
	node->next = NULL;
	return node;
} 
//釋放結(jié)點
void freeNode(Node *node){
	if(!node) return ;
	free(node);
} 

只有單一結(jié)點指針的鏈表的全程是“單鏈表”,經(jīng)常被簡稱為鏈表。

鏈表的管理結(jié)點一般僅需要存放頭結(jié)點指針(*head)。

如果需要頻繁獲取鏈表長度,管理結(jié)點中可以額外存放鏈表長度(len)。

//定義鏈表 管理結(jié)點 
typedef struct List{
	Node *head;
	int len;
} List;
//初始化鏈表
List *initList() {
	List *list = (List *) malloc(sizeof(List));
	list->head = NULL;
	list->len = 0;
	return list;
}

2.2 頭部插入

頭插法:將新插入的節(jié)點放在 head 后,時間復(fù)雜度O(1)

//頭部插入
void insertToHead(List *list, int val){
	if(!list) return ;
	Node *node = initNode(val);
	node->next = list->head;
	list->head = node;
	list->len++;
} 

2.3 尾部插入

尾插法:找到最后一個結(jié)點,將新節(jié)點插入。如果沒有設(shè)計尾指針,則時間復(fù)雜度為O(n)。

//尾部插入 
void insertToTail(List *list, int val){
	if(!list) return ;
	Node *node = initNode(val);
	//如果list為空 則node為第一個結(jié)點 讓head等于node
	//判斷條件可更改為list->len == 0 
	if(list->head == NULL){
		list->head = node;
		list->len++;
		return ;
	}
	Node *p = list->head;
	while(p->next != NUll){
		p = p->next;
	}
	p->next = node;
	list->len++;
}
//測試
int main(){
	List *list1 = initList();
	List *list2 = initList();
	for(int i = 0;i <= 10;i += 2){
		insertToHead(list1,i);
	}
	Node *p = list1->head;
	while(p){
		printf("%d -> ",p->val);
		p = p->next;
	}
	printf("\n");
	for(int i = 1;i <= 10;i += 2){
		insertToTail(list2,i);
	}
	Node *q = list2->head;
	while(q){
		printf("%d -> ",q->val);
		q = q->next;
	}
	printf("\n");
	return 0;
}

輸出結(jié)果:

2.4 任意位置插入

//任意位置的插入
// idx = 0 待插入結(jié)點為頭結(jié)點
// idx > 0 插入至第 i 個結(jié)點后
void insert(List *list, int idx, int val){
	if(!list) return ;
	if(idx > list->len || idx < 0) return ;
	if(idx == 0){
		//頭插法 
		insertToHead(list,val);
		return;
	}
	Node *node = initNode(val);
	//結(jié)點索引為 0 
	Node *p = list->head;
	//p 找到第 idx - 1個結(jié)點
	// i = 1  結(jié)點索引為 1 
	// i = 2 結(jié)點索引為 2
	// i = idx - 1 結(jié)點索引為 idx - 1 
	for(int i = 1;i <= idx - 1;i++){
		p = p->next;
	} 
	//插入
	node->next = p->next;
	p->next = node;
	list->len++;
}

2.5 任意位置刪除

//任意位置的刪除 
void remove(List *list, int idx){
	if(!list) return ;
	if(idx > list->len || idx < 0) return ;
	//p為0號索引結(jié)點
	Node *p = list->head;
	//刪除索引為 0 的結(jié)點 更改head 
	if(idx == 0){
		list->head = p->next; 
		list->len--;
		freeNode(p);
		return;
	}
	//找到idx-1個結(jié)點
	for(int i = 1;i <= idx - 1;i ++){
		p = p->next;
	}
	Node *node = p->next;
	//刪除 
	p->next = p->next->next;
	list->len--;
	freeNode(node);
} 

2.6 虛頭結(jié)點

在需要特殊處理頭結(jié)點的時候,可以實現(xiàn)一個帶有虛頭結(jié)點的鏈表。在鏈表初始化或在某些操作執(zhí)行時,將一個額外的結(jié)點放在頭指針執(zhí)行的地方。虛頭結(jié)點可以使得整個鏈表永遠(yuǎn)不空,永遠(yuǎn)有頭。所以擁有虛頭結(jié)點的鏈表在處理各類結(jié)點操作時會更加便捷。

任意位置插入:不需要特殊考慮插入位置是否在鏈表頭部。

任意位置刪除:不需要特殊考慮刪除的結(jié)點是否是鏈表的第一個結(jié)點。

//結(jié)點部分沒有改動
//定義結(jié)點 
typedef struct Node{
	int val;
	struct Node *next;
} Node; 
//結(jié)點初始化 
Node *initNode(int val){
	Node *node = (Node *) malloc(sizeof(Node));
	node->val = val;
	node->next = NULL;
	return node;
} 
//釋放結(jié)點
void freeNode(Node *node){
	if(!node) return ;
	free(node);
}

//定義鏈表 管理結(jié)點 
typedef struct List{
	Node *head;
	int len;
} List;
//初始化鏈表
List *initList() {
	List *list = (List *) malloc(sizeof(List));
	//變動  :初始化的時候賦予一個結(jié)點 任意數(shù)值都可以 
	list->head = initNode(-1);
	list->len = 0;
	return list;
}
//頭部插入
void insertToHead(List *list, int val){
	if(!list) return ;
	Node *node = initNode(val);
	// 變動
	node->next = list->head->next;
	// 變動
	list->head->next = node;
	list->len++;
} 
//尾部插入 
void insertToTail(List *list, int val){
	if(!list) return ;
	Node *node = initNode(val);
	//變動 刪除對鏈表是否為空的判斷  可以直接進(jìn)行插入
	//此處可以謝偉 Node *p = list->head->next; 
	Node *p = list->head;
	while(p->next != NULL){
		p = p->next;
	}
	p->next = node;
	list->len++;
}
//任意位置的插入
void insert(List *list, int idx, int val){
	if(!list) return ;
	if(idx > list->len || idx < 0) return ;
	//變動 : 刪除對鏈表是否為空的判斷 
	Node *node = initNode(val);
	Node *p = list->head;
	for(int i = 1;i <= idx;i++){
		p = p->next;
	} 
	//插入
	node->next = p->next;
	p->next = node;
	list->len++;
} 
//任意位置的刪除 
void remove(List *list, int idx){
	if(!list) return ;
	if(idx > list->len || idx < 0) return ;
	Node *p = list->head;
	for(int i = 1;i <= idx;i ++){
		p = p->next;
	}
	Node *node = p->next;
	//刪除 
	p->next = p->next->next;
	list->len--;
	freeNode(node);
}

到此這篇關(guān)于C語言超詳細(xì)講解線性表的文章就介紹到這了,更多相關(guān)C語言線性表內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Opencv開發(fā)實現(xiàn)拼圖游戲

    Opencv開發(fā)實現(xiàn)拼圖游戲

    這篇文章主要為大家詳細(xì)介紹了Opencv開發(fā)實現(xiàn)拼圖游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-07-07
  • 詳解C++ STL vector容量(capacity)和大小(size)的區(qū)別

    詳解C++ STL vector容量(capacity)和大小(size)的區(qū)別

    這篇文章主要介紹了詳解C++ STL vector容量(capacity)和大小(size)的區(qū)別,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-05-05
  • C語言之選擇分支語句詳解

    C語言之選擇分支語句詳解

    大家好,本篇文章主要講的是C語言之選擇分支語句詳解,感興趣的同學(xué)趕快來看一看吧,對你有幫助的話記得收藏一下,方便下次瀏覽
    2021-12-12
  • C語言實現(xiàn)萬年歷源碼

    C語言實現(xiàn)萬年歷源碼

    這篇文章主要為大家詳細(xì)介紹了C語言實現(xiàn)萬年歷源碼,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-10-10
  • 算法詳解之分治法具體實現(xiàn)

    算法詳解之分治法具體實現(xiàn)

    這篇文章主要介紹了算法詳解之分治法具體實現(xiàn),需要的朋友可以參考下
    2014-02-02
  • 面向?qū)ο笕筇匦缘囊饬x講解

    面向?qū)ο笕筇匦缘囊饬x講解

    今天小編就為大家分享一篇關(guān)于面向?qū)ο笕筇匦缘囊饬x講解,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2018-12-12
  • C語言堆排序經(jīng)典算法TopK問題解析

    C語言堆排序經(jīng)典算法TopK問題解析

    這篇文章主要為大家介紹了C語言堆排序經(jīng)典算法TopK問題解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-04-04
  • c++ vector 常用函數(shù)示例解析

    c++ vector 常用函數(shù)示例解析

    這篇文章主要介紹了c++ vector 常用函數(shù)示例解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • C++中的繼承模式深入詳解

    C++中的繼承模式深入詳解

    這篇文章主要介紹了C++中的繼承模式深入詳解。繼承是OOP設(shè)計中的重要概念。在C++語言中,派生類繼承基類有三種繼承方式:私有繼承(private)、保護(hù)繼承(protected)和公有繼承(public)。
    2021-03-03
  • C++ deque容器的具體使用

    C++ deque容器的具體使用

    deque又稱雙端隊列容器。deque容器中存儲元素并不能保證所有元素都存儲到連續(xù)的內(nèi)存空間中,本文詳細(xì)的介紹了C++ deque容器的使用,感興趣的可以了解一下
    2021-05-05

最新評論

南川市| 罗平县| 凤庆县| 上饶市| 沙田区| 丹江口市| 和政县| 德惠市| 灌云县| 托克托县| 龙江县| 牙克石市| 奇台县| 哈密市| 尉犁县| 澄城县| 沙坪坝区| 雷波县| 扬州市| 五家渠市| 西城区| 宜宾县| 济南市| 肃南| 天峻县| 昌宁县| 通辽市| 新龙县| 无为县| 中西区| 荆门市| 镇宁| 马鞍山市| 新晃| 乌审旗| 兴宁市| 景宁| 柳江县| 维西| 二连浩特市| 伊川县|