線性結構_鏈表

1、定義:
n個節點離散分配;
每個節點只有一個前驅結點,每個節點只有一個後續節點;
首節點沒有前驅結點,尾節點沒有後續節點;

2、專業術語:
頭節點:第一個有效節點之前的節點,方便對鏈表進行操作,並不存放有效數據,頭節點的數據類型與首節點一致;
首節點:第一個有效節點;
尾節點:最後一個有效節點;
頭指針:指向頭節點的指針變量;
尾指針:指向尾節點的指針變量。

3、如果希望通過一個函數來對鏈表進行處理,我們至少需要接受鏈表那些信息:
只需要一個參數:頭指針,通過頭指針可以推算出鏈表的其他所有信息。

4、分類:
單鏈表:
雙鏈表:每個節點有2個指針域。
循環鏈表:能通過任何一個節點找到所有節點。

5、算法:
遍歷
查找
清空
銷燬
求長度
排序
刪除節點
插入節點

(要點,先臨時定義一個指向p後面節點的指針r)
(在p後面插入節點q)
r = p->pNext; p->pNext = q;(p指向q) q->qNext = r;(q指向下一個節點)
q->pNext = p->pNext; p->pNext = q;

(刪除p後面的節點)
r = p->pNext;
p->pNext = p->pNext->pNext;
free(r);

6、算法:
狹義的算法是與數據的存儲方式密切相關的。
廣義的算法是與數據的存儲方式無關的。
泛型:利用某種技術達到的效果就是:不用的存儲方式,執行的操作是一樣的。
#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>

typedef struct Node {
	int data;	//數據域
	struct Node* pNext;		//指針域,存放下一個節點的地址
} NODE , *PNODE;			//NODE相當於struct Node 類型,*PNODE想當與struct Node*類型

PNODE create_List(void);	//創建非循環單鏈表

void traverse_List(PNODE pHead);//遍歷鏈表

bool is_Empty(PNODE pHead);	//判斷鏈表是否爲空

int length_List(PNODE pHead);//求鏈表的長度

bool insert_List(PNODE, int, int);//向鏈表插入數據,第一個參數是鏈表的頭節點,第二個參數是插入的位置,第三個是插入的值(data)

bool delete_List(PNODE, int, int*);//刪除某個節點,第一個參數是鏈表的頭節點,第二個參數是刪除節點的位置,第三個是刪除節點的值(data)

void sort_List(PNODE);		//對鏈表進行排序

int main() {
	PNODE pHead = NULL;		//等價於 struct Node* pHead = null

	pHead = create_List();	//創建一個非循環單鏈表,並把鏈表首地址賦給pHead

	if (is_Empty(pHead)) {
		printf("該鏈表爲空。\n");
	}
	else {
		printf("鏈表不爲空。\n");
		int len = length_List(pHead);
		printf("鏈表的長度爲:%d\n", len);
	}

	traverse_List(pHead);	//遍歷鏈表

	sort_List(pHead);
	traverse_List(pHead);	//遍歷鏈表

	return 0;
}

PNODE create_List(void) {
	int len;				//鏈表節點個數
	int val;				//用來臨時存放用戶輸入的數據data
	//分配了一個不存放有效數據的頭節點
	PNODE pHead = (PNODE)malloc(sizeof(NODE));
	if (NULL == pHead) {
		printf("分配失敗,程序終止!");
		exit(-1);
	}
	//pTail與pHead都指向頭節點
	PNODE pTail = pHead;
	//避免當鏈表節點個數爲0,程序崩潰
	pTail->pNext = NULL;

	printf("請輸入你要生成的鏈表的節點個數:");
	scanf("%d", &len);
	for (int i = 0; i < len; ++i) {
		printf("請輸入第%d個節點的數據:" , i+1);
		scanf("%d", &val);
		PNODE pNew = (PNODE)malloc(sizeof(NODE));
		if (NULL == pHead) {
			printf("分配失敗,程序終止!");
			exit(-1);
		}
		pNew->data = val;
		//pTali永遠指向尾節點
		pTail->pNext = pNew;	//pTail指向新節點
		pNew->pNext = NULL;		//把新節點的指針域清空
		pTail = pNew;			//將新節點pNew放置到pTail
	}
	return pHead;
}


void traverse_List(PNODE pHead) {
	PNODE p = pHead->pNext;
	while (NULL != p) {
		printf("%d ", p->data);
		p = p->pNext;
	}
	printf("\n");
	return;
}

bool is_Empty(PNODE pHead) {
	if (NULL == pHead->pNext) {
		return true;
	}
	else return false;
}

int length_List(PNODE pHead) {
	PNODE p = pHead->pNext;
	int len = 0;
	while (NULL != p) {
		len++;
		p = p->pNext;
	}
	return len;
}


void sort_List(PNODE pHead) {

	/*簡單的冒泡排序
	int i, j, t;
	for (i = 0; i < len - 1; i++) {
		for (j = i + 1; j < len; j++) {
			if (a[i] > a[j]) {
				t = a[i];
				a[i] = a[j];
				a[j] = t;
			}
		}
	}
	return;*/
	int i, j, t;
	int len = length_List(pHead);
	PNODE p, q;
	for (i = 0, p = pHead->pNext; i < len - 1; i++, p = p->pNext) {
		for (j = i + 1, q = p->pNext; j < len; j++, q = q->pNext) {
			if (p->data > q->data) {
				t = p->data;
				p->data = q->data;
				q->data = t;
			}
		}
	}
	return;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章