單鏈表的基本操作

本博文僅記錄學習使用,您可以在這裏看我的詳細筆記

#include <stdio.h>
#include <stdlib.h>
// typedef struct Node{...}Node;
// 在學習 C 語言的時候,我們直到 struct 後面的 Node 是可以
// 省略的,但是這裏必須加上,因爲在結構體內部定義了後驅尾
// 該結構,這個時候,在運行代碼的時候,最後的末尾的 Node 沒有
// 運行到,會報錯  
typedef int ElemType;
typedef int Status;
 
typedef struct Node
{
	ElemType data;
	struct Node *next;
}Node;

// 就是把 struct Node * 定義成了新類型 LinkList。
// 這個類型是一個結構體的指針。
typedef struct Node *LinkList;

// 單鏈表的創建(頭插法 
//void CreateListHead(LinkList *L,int n)
//{
//	// 創建一個新結點 p 
//	LinkList p;
//	int i;
//	// 初始化一個空鏈表 
//	*L = (LinkList)malloc(sizeof(Node));
//	// L 的頭結點指針指向 NULL,這是一個帶頭結點的單鏈表 
//	(*L)->next = NULL;
//	for(i=0;i<n;i++)
//	{
//		p = (LinkList)malloc(sizeof(Node));
//		p->data = i;
//		p->next = (*L)->next;
//		(*L)->next =p;
//	}
//} 

// 單鏈表的創建(尾插法)
// n 表示插入的個數 
void CreateListTail(LinkList *L,int n)
{
	LinkList p,r;
	int i;
	*L = (LinkList)malloc(sizeof(Node));
	// r 指向當前鏈表,注意這裏的 L 和頭插法中的 L
	// 有區別,這裏的 L 是指的整個鏈表 
	// r 是 rear(尾部)的縮寫,此時 r 當作尾結點(因爲
	// 當前還沒有新插入的結點 p ,所以認爲 r 是頭結點也對) 
	r = *L;
	for(i=0;i<n;i++)
	{
		p=(LinkList)malloc(sizeof(Node));
		p->data = i;
		// 此時 r 爲前一個結點,新創建的結點 p
		// 被放在 r 後面(尾插) 
		r->next = p;
		// 然後讓 r 變成 p,這樣 r 又可以作爲尾結點 
		r = p;
	} 
	r->next = NULL; 
	printf("創建成功\n");
} 

// 單鏈表的整表刪除
Status ClearList(LinkList *L)
{
	LinkList p,q;
	while(p)
	{
		q = p->next;
		free(p);
		p=q;
	}
	(*L)->next = NULL;
	printf("刪除成功\n");
	return 1;
	
} 
 

// 單鏈表的讀取
// i 表示要讀取的位置序號
// e 接收讀取值的變量 
Status GetElem(LinkList L,int i,ElemType *e)
{
	int j=1;    // 爲計數器 
	LinkList p; // 聲明一個額外的結點
	p = L->next; // 將 p 指向鏈表的第一個結點
	while(p && j<i) // 當 p 不爲空,且搜索到的邏輯序號接近(當下一個就是目標節點)數目標結點的序號停止 
	{
		p = p->next;
		++j; 
	} 
	
	if(!p||j>i)
		return 0;
	*e = p->data;
	return 1;
}

// 插入
// i 表示要插入的位置
// e 表示要插入的值 
Status ListInsert(LinkList *L,int i,ElemType e)
{
	int j;
	LinkList p,s;
	p = *L; // p 指向鏈表的第一個結點 
	j=1;
	while(p && j<i)
	{
		p = p->next; // p 不斷去搜索目標結點 
		++j;
	}
	
	if(!p || j<i)
		return 0;
		
	s = (LinkList)malloc(sizeof(Node)); // 系統生成 s 作爲被插入的結點 
	s->data = e; // 給 s 賦值 
	s->next = p->next;
	p->next = s;
	return 1;
} 

// 刪除
// i 表示要刪除的位置
// e 表示返回的被刪除的值 
Status ListDelete(LinkList *L,int i,ElemType *e)
{
	int j;
	LinkList p,q;
	p = *L;
	j = 1;
	// 通過這個循環我們找到要刪除的元素的位置 
	while(p->next && j<i)
	{
		p = p->next;
		++j;
	}
	
	if(!(p->next) || j>i)
		return 0;
	q = p->next;
	p->next = q->next;
	*e = q->data;
	// free 用於釋放一個內存地址 
	free(q);
	return 1;
} 

// 顯示當前鏈表所有元素
Status showList(LinkList L)
{
	LinkList temp;
	temp = L->next;
	printf("當前鏈表所有元素:");
	while(temp)
	{
		printf("%d ",temp->data);
		temp = temp->next;
	}
	printf("\n");
} 

main()
{
	LinkList L;
	int e; 
	// 創建大小爲 10 的鏈表 
	int n = 10; 
	CreateListTail(&L,n);
	// 讀取 
	GetElem(L,5,&e);
	printf("讀取到的數值是:%d\n",e);
	// 插入 
	ListInsert(&L,5,e);
	// 顯示
	showList(L); 
	// 刪除
	ListDelete(&L,5,&e);
	printf("刪除的數值是:%d\n",e);
	// 顯示
	showList(L);
	// 整表刪除
	ClearList(&L);
	// 顯示
	showList(L);	 
	 
}

在這裏插入圖片描述

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