單鏈表的基本操作(第一篇)


 

  學習數據結構的筆記

1.在線性表的鏈式存儲中,頭指針與頭結點之間的根本區別以及頭結點與開始結點的關系:

  鏈表的頭指針一般指向其第一個結點,他有標識鏈表的作用。頭結點的作用在於統一相關操作,頭結點的數據域一般沒有意義,在某些情況下可以存放鏈表長   度。如果鏈表含有頭結點,無論鏈表是   否為空,頭指針均不為空。開始結點也就是鏈表中存儲數據的第一個結點,它是頭結點后邊的第一個結點。

2.比較順序表和鏈表各自的特點:

(1)存儲分配的方式:順序表的存儲空間是靜態分配的。鏈表的存儲空間是動態分配的。

(2)存儲密度(存儲密度=結點值域所占的存儲量/結點結構所占的存儲總量):順序表存儲密度=1。鏈表<1。

(3)存取方式:順序表可以隨機存取,也可以順序存取。鏈表是順序存取的。

(4)插入刪除時移動元素的個數:順序表平均移動近一半元素。鏈表不需要移動元素,只需要修改指針。

 

單鏈表基本操作的C語言實現代碼:

單鏈表結點的定義:

/*👇一個單向鏈表結點的聲明,結點串在一起就是一個鏈表*/
typedef struct LinkNode
{
	int data; //存儲的內容,簡單得用 int 演示
	LinkNode* next; //如何知道下一個結點在哪里呢?可以保存下一個結點的地址
}LinkNode;

  

初始化:

/*👇1.鏈表的初始化*/
//LinkNode* head 指明頭結點地址,要初始化哪一個鏈表
void Init_LinkList(LinkNode* head)
{
	head->next = NULL; //頭結點的 next 指向地址0,表示沒有內容
}

  

單鏈表的插入(也是建立單鏈表的過程):

/*👇2.鏈表的插入*/
//LinkNode* head 指明頭結點地址,要初始化那一個鏈表
//int e 要插入結點的內容
//int index 要插入的位置,規定從1標號。以下的代碼不對index的范圍做檢查,假定輸入的范圍都是對的。
void Insert_LinkList(LinkNode* head, int e, int index)
{
	//由於是單向鏈表,必須找到插入位置的前驅結點,比如要插入2位置必須先找到1位置。因為有頭結點保證一定有前驅結點。
	int i;
	LinkNode* prev, *node;

	prev = head; //前驅結點
	for (i = 1; i < index; i++)
		prev = prev->next;
	//👆前驅結點找到

	node = (LinkNode*)malloc(sizeof(LinkNode));
	node->data = e;
	//👆為插入的結點分配內存並賦值

	//👇關鍵的插入步驟
	//要在prev結點和prev->next結點之間插入node,注意賦值順序,理解一下為什么一定要是這個順序
	node->next = prev->next;
	prev->next = node;
}

  

單鏈表的刪除:

/*👇3.鏈表的刪除*/
int Delet_LinkList(LinkNode* head, int index)
{
	int i;
	LinkNode* prev, *node;

	prev = head; //前驅結點
	for (i = 1; i < index; i++)
		prev = prev->next;
	//👆前驅結點找到

	//👇關鍵的刪除步驟
	node = prev->next;
	int e = node->data;
	prev->next = node->next;
	free(node);

	return e;
}

  

按序號查找結點值:

/*👇4.按序號查找結點值*/
void IdSearch_List(LinkNode * head, int index)
{
	int i = 1;
	LinkNode * prev;
	prev = head->next;
	while (i != index)////////////////////////////////////////////👈是在index范圍正確的情況下可以。注意一下。
	{
		prev = prev->next;
		i++;
	}
	printf("%d", prev->data);
}

  

按值查找表結點:

/*👇5.按值查找表結點*/
int ValueSearch_List(LinkNode * head, int e)
{
	int i = 1;
	LinkNode *prev;
    prev = head->next;
	while (prev != NULL&&prev->data != e)
	{
		prev = prev->next;
		i++;
	}
	if (prev == NULL)
	{
        printf("該值不存在!\n");
		return NULL;
	}
	else if (prev->data == e)
	{
		return i;
	}
}

  

打印:

//寫個調試打印更直觀,直接看調試窗口也可以
void print_list(LinkNode* head)
{
	for (head = head->next; head != NULL; head = head->next)
		printf("%d -> ", head->data);

	printf("\n");
}

  

主函數:

/*👇定義一個鏈表的頭結點,頭結點只做定位用,指明是哪個單向鏈表的開始,里面data域雖然也占用空間但用不上。*/
LinkNode List_head;

 

/*直接在main函數里用Insert_LinkList建表,當然也有尾插法建表(直接插head后面)*/
int main()
{
	Init_LinkList(&List_head); //初始化一下

	Insert_LinkList(&List_head, 3, 1);
	print_list(&List_head);
	Insert_LinkList(&List_head, 1, 2);
	print_list(&List_head);
	Insert_LinkList(&List_head, 6, 3);
	print_list(&List_head);
	Insert_LinkList(&List_head, 4, 4);
	print_list(&List_head);
	printf("\n");

	int value = Delet_LinkList(&List_head, 1);
	//Delet_LinkList(&List_head,  3);//注意上面一步已經刪除了第三個位置元素,加上這一句將會再刪除一次
	print_list(&List_head);
	printf("刪除的結點值為:%d\n", value);
	printf("\n");

	printf("序號為2查找的結點的值為:");
	IdSearch_List(&List_head, 2);
	printf("\n");
	printf("\n");//純屬為了輸出界面看得清楚而已

	int index = ValueSearch_List(&List_head, 6);
	printf("結點值為6的結點位置為:%d", index);
	printf("\n");
	printf("\n");

	//ValueSearch_List(&List_head, 1000);//調用看看
	return 0;
}

 

運行結果:

  

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM