1. 程式人生 > >資料結構之靜態順序表和動態順序表

資料結構之靜態順序表和動態順序表

@Sock對靜態順序表和動態順序表的總結

簡單概括他們的異同點

相同點:記憶體空間連續, 資料順序儲存

不同點:它們所佔記憶體空間的位置不同, 靜態定義一個順序表, 順序表所佔的記憶體空間開闢在記憶體的靜態區, 即所謂的函式棧上, 隨著函式呼叫的結束, 這塊記憶體區域會被系統自動回收; 而動態生成一個順序表, 順序表所佔的記憶體空間開闢在記憶體的動態區, 即所謂的堆記憶體上, 這塊區域不會隨著函式呼叫的結束被系統自動回收, 而是需要程式設計師主動去釋放它.

各自優點(個人認為)

靜態順序表:操作簡單, 不用手動釋放其記憶體空間, 不存在記憶體洩漏

動態順序表:可以動態開闢記憶體空間, 操作靈活, 避免不必要的開銷

靜態順序表的實現

定義一個靜態順序表

//定義一個靜態順序表
#define MAXSIZE 100
typedef int ElemType;
ElemType SqList[MAXSIZE];
int len;

向靜態順序表中插入元素

//向靜態順序表中插入元素
void InsertElem(ElemType* S, int* len, int pos, ElemType e) {
	//判斷插入位置是否合理
	if (*len == MAXSIZE || pos < 1 || pos > *len + 1) {
		printf("表滿或插入位置不合理\n");
		exit(0);
	}
	//調整插入位置, 準備插入指定元素
	for (int i = *len - 1; i >= pos - 1; --i) {
		*(S + i + 1) = *(S + i);
	}
	//插入指定元素
	*(S + pos - 1) = e;
	//元素個數加 1
	++(*len);
}

從靜態順序表中刪除元素

//向靜態順序表中刪除元素
void DelElem(ElemType* S, int* len, int pos) {
	//判斷刪除位置是否合理
	if (pos < 1 || pos > *len) {
		printf("刪除位置不合理\n");
		exit(0);
	}
	//調整刪除位置, 準備刪除指定元素
	for (int i = pos; i < *len; ++i) {
		*(S + i - 1) = *(S + i);
	}
	//元素個數減 1
	--(*len);
}

遍歷靜態順序表

//遍歷順序表
void Traverse(ElemType* S) {
	for (int i = 0; i < len; ++i) {
		printf("%d ", *(S + i));
	}
	printf("\n");
}

測試

#include <stdio.h>
#include <windows.h>

//定義一個靜態順序表
#define MAXSIZE 100
typedef int ElemType;
ElemType SqList[MAXSIZE];
int len;

//向靜態順序表中插入元素
void InsertElem(ElemType* S, int* len, int pos, ElemType e) {
	//判斷插入位置是否合理
	if (*len == MAXSIZE || pos < 1 || pos > *len + 1) {
		printf("表滿或插入位置不合理\n");
		exit(0);
	}
	//調整插入位置, 準備插入指定元素
	for (int i = *len - 1; i >= pos - 1; --i) {
		*(S + i + 1) = *(S + i);
	}
	//插入指定元素
	*(S + pos - 1) = e;
	//元素個數加 1
	++(*len);
}

//向靜態順序表中刪除元素
void DelElem(ElemType* S, int* len, int pos) {
	//判斷刪除位置是否合理
	if (pos < 1 || pos > *len) {
		printf("刪除位置不合理\n");
		exit(0);
	}
	//調整刪除位置, 準備刪除指定元素
	for (int i = pos; i < *len; ++i) {
		*(S + i - 1) = *(S + i);
	}
	//元素個數減 1
	--(*len);
}

//遍歷順序表
void Traverse(ElemType* S) {
	for (int i = 0; i < len; ++i) {
		printf("%d ", *(S + i));
	}
	printf("\n");
}

int main() {
	len = 5;
	for (int i = 0; i < len; ++i) {
		*(SqList + i) = i + 1;
	}
	Traverse(SqList);
	InsertElem(SqList, &len, 4, 100);
	Traverse(SqList);
	DelElem(SqList, &len, 4);
	Traverse(SqList);
	system("pause");
	return 0;
}

效果圖
在這裡插入圖片描述

動態順序表的實現

定義一個動態順序表

//定義一個動態順序表
#define MAXSIZE 100
#define LISTINCREMENT 10
typedef int ElemType;
typedef struct SqList {
	ElemType* elem;
	int len;
	int listsize;
}SqList;

初始化

//初始化一個動態順序表
void InitList(SqList* S) {
	//動態生成了一個指定大小的順序表
	S->elem = (ElemType*)malloc(MAXSIZE * sizeof(ElemType));
	if (!S->elem) {
		printf("建立失敗\n");
		exit(0);
	}
	S->len = 0;
	S->listsize = MAXSIZE;
}

向動態順序表中插入元素

//向動態順序表中插入元素
void InsertElem(SqList* S, int pos, ElemType e) {
	//判斷插入位置是否合理
	if (pos < 1 || pos > S->len + 1) {
		printf("插入位置不合理\n");
		return;// exit(0);
	}
	//判斷表是否為滿
	if (S->len == S->listsize) {
		S->elem = (ElemType*)realloc(S->elem, (S->listsize + LISTINCREMENT) * sizeof(ElemType));
		S->listsize += LISTINCREMENT;
	}
	//調整插入位置, 準備插入指定元素
	for (int i = S->len - 1; i >= pos - 1; --i) {
		*(S->elem + i + 1) = *(S->elem + i);
	}
	//插入指定元素
	*(S->elem + pos - 1) = e;
	//元素個數加 1
	++S->len;
}

從動態順序表中刪除元素

//從動態順序表中刪除元素
void DelElem(SqList* S, int pos) {
	//判斷刪除位置是否合理
	if (pos < 1 || pos > S->len) {
		printf("刪除位置不合理\n");
		return;// exit(0);
	}
	//調整刪除位置, 準備刪除指定元素
	for (int i = pos; i < S->len; ++i) {
		*(S->elem + i - 1) = *(S->elem + i);
	}
	//元素個數減 1
	--S->len;
}

遍歷動態順序表

//遍歷順序表
void Traverse(SqList S) {
	for (int i = 0; i < S.len; ++i) {
		printf("%d ", *(S.elem + i));
	}
	printf("\n");
}

銷燬一個動態順序表

//銷燬一個動態順序表
void DestroyList(SqList* S) {
	//釋放堆記憶體
	free(S->elem);
	S->elem = NULL;
	S->len = 0;
	S->listsize = 0;
	printf("銷燬成功\n");
}

清空一個動態順序表

//清空一個動態順序表
void ClearList(SqList* S) {
	//令元素個數為 0
	S->len = 0;
	printf("已清空\n");
}

判斷動態順序表是否為空

//判斷動態順序表是否為空
int IsEmpty(SqList S) {
	if (S.len == 0) {
		//printf("表為空\n");
		return 1;
	}
	//printf("表不為空\n");
	return 0;
}

獲取動態順序表上指定位置的值

//獲取動態順序表上某個位置上的值
int GetElem(SqList S, int pos) {
	//判斷獲取位置是否合理
	if (pos < 1 || pos > S.len) {
		printf("獲取位置不合理\n");
		return 0;// exit(0);
	}
	return *(S.elem + pos - 1);
}

在動態順序表中查詢指定值

//在動態順序表中查詢指定值
void LocateElem(SqList S, ElemType e) {
	//遍歷順序表
	for (int i = 0; i < S.len; ++i) {
		if (*(S.elem + i) == e) {
			printf("找到了該元素, 它是第 %d 個元素\n", i + 1);
			return;
		}
	}
	printf("沒有找到該元素\n");
}

在動態順序表中查詢指定元素的前驅

//在動態順序表中找某個元素的前驅
ElemType ProriElem(SqList S, ElemType cur_e) {
	//判斷是否為第一個元素
	if (*S.elem == cur_e) {
		printf("第一個元素沒有前驅\n");
		return 0;
	}
	//從第二個元素開始查詢
	for (int i = 1; i < S.len; ++i) {
		if (*(S.elem + i) == cur_e) {
			//返回該元素的前驅
			return *(S.elem + i - 1);
		}
	}
	printf("沒有該元素\n");
	return 0;
}

在動態順序表中查詢指定元素的後繼

//在動態順序表中找某個元素的後繼
ElemType NextElem(SqList S, ElemType cur_e) {
	//判斷是否為最後一個元素
	if (*(S.elem + S.len - 1) == cur_e) {
		printf("最後一個元素沒後繼\n");
		return 0;
	}
	//從頭一直查到倒數第 2 個元素
	for (int i = 0; i < S.len - 1; ++i) {
		if (*(S.elem + i) == cur_e) {
			//返回該元素的後繼	
			return *(S.elem + i + 1);
		}
	}
	printf("沒有該元素\n");
	return 0;
}

測試

#include <stdio.h>
#include <windows.h>

//定義一個動態順序表
#define MAXSIZE 100
#define LISTINCREMENT 10
typedef int ElemType;
typedef struct SqList {
	ElemType* elem;
	int len;
	int listsize;
}SqList;

//初始化一個動態順序表
void InitList(SqList* S) {
	//動態生成了一個指定大小的順序表
	S->elem = (ElemType*)malloc(MAXSIZE * sizeof(ElemType));
	if (!S->elem) {
		printf("建立失敗\n");
		exit(0);
	}
	S->len = 0;
	S->listsize = MAXSIZE;
}

//向動態順序表中插入元素
void InsertElem(SqList* S, int pos, ElemType e) {
	//判斷插入位置是否合理
	if (pos < 1 || pos > S->len + 1) {
		printf("插入位置不合理\n");
		return;// exit(0);
	}
	//判斷表是否為滿
	if (S->len == S->listsize) {
		S->elem = (ElemType*)realloc(S->elem, (S->listsize + LISTINCREMENT) * sizeof(ElemType));
		S->listsize += LISTINCREMENT;
	}
	//調整插入位置, 準備插入指定元素
	for (int i = S->len - 1; i >= pos - 1; --i) {
		*(S->elem + i + 1) = *(S->elem + i);
	}
	//插入指定元素
	*(S->elem + pos - 1) = e;
	//元素個數加 1
	++S->len;
}

//從動態順序表中刪除元素
void DelElem(SqList* S, int pos) {
	//判斷刪除位置是否合理
	if (pos < 1 || pos > S->len) {
		printf("刪除位置不合理\n");
		return;// exit(0);
	}
	//調整刪除位置, 準備刪除指定元素
	for (int i = pos; i < S->len; ++i) {
		*(S->elem + i - 1) = *(S->elem + i);
	}
	//元素個數減 1
	--S->len;
}

//銷燬一個動態順序表
void DestroyList(SqList* S) {
	//釋放堆記憶體
	free(S->elem);
	S->elem = NULL;
	S->len = 0;
	S->listsize = 0;
	printf("銷燬成功\n");
}

//清空一個動態順序表
void ClearList(SqList* S) {
	//令元素個數為 0
	S->len = 0;
	printf("已清空\n");
}

//判斷動態順序表是否為空
int IsEmpty(SqList S) {
	if (S.len == 0) {
		//printf("表為空\n");
		return 1;
	}
	//printf("表不為空\n");
	return 0;
}

//獲取動態順序表上某個位置上的值
int GetElem(SqList S, int pos) {
	//判斷獲取位置是否合理
	if (pos < 1 || pos > S.len) {
		printf("獲取位置不合理\n");
		return 0;// exit(0);
	}
	return *(S.elem + pos - 1);
}

//在動態順序表中查詢指定值
void LocateElem(SqList S, ElemType e) {
	//遍歷順序表
	for (int i = 0; i < S.len; ++i) {
		if (*(S.elem + i) == e) {
			printf("找到了該元素, 它是第 %d 個元素\n", i + 1);
			return;
		}
	}
	printf("沒有找到該元素\n");
}

//在動態順序表中找某個元素的前驅
ElemType ProriElem(SqList S, ElemType cur_e) {
	//判斷是否為第一個元素
	if (*S.elem == cur_e) {
		printf("第一個元素沒有前驅\n");
		return 0;
	}
	//從第二個元素開始查詢
	for (int i = 1; i < S.len; ++i) {
		if (*(S.elem + i) == cur_e) {
			//返回該元素的前驅
			return *(S.elem + i - 1);
		}
	}
	printf("沒有該元素\n");
	return 0;
}

//在動態順序表中找某個元素的後繼
ElemType NextElem(SqList S, ElemType cur_e) {
	//判斷是否為最後一個元素
	if (*(S.elem + S.len - 1) == cur_e) {
		printf("最後一個元素沒後繼\n");
		return 0;
	}
	//從頭一直查到倒數第 2 個元素
	for (int i = 0; i < S.len - 1; ++i) {
		if (*(S.elem + i) == cur_e) {
			//返回該元素的後繼	
			return *(S.elem + i + 1);
		}
	}
	printf("沒有該元素\n");
	return 0;
}

//遍歷順序表
void Traverse(SqList S) {
	for (int i = 0; i < S.len; ++i) {
		printf("%d ", *(S.elem + i));
	}
	printf("\n");
}

int main() {
	SqList S1;
	InitList(&S1);
	//填寫 5 個數據
	for (int i = 0; i < 5; ++i) {
		*(S1.elem + i) = i + 1;
		++S1.len;
	}
	Traverse(S1);
	InsertElem(&S1, 4, 100);
	Traverse(S1);
	int value = GetElem(S1, 4);
	printf("%d\n", value);
	LocateElem(S1, 100);
	int prori_e = ProriElem(S1, 100);
	printf("%d\n", prori_e);
	int next_e = NextElem(S1, 100);
	printf("%d\n", next_e);
	DelElem(&S1, 4);
	Traverse(S1);
	system("pause");
	return 0;
}

效果圖
在這裡插入圖片描述

希望大家能夠理解!!!