單鏈表創建,取值,查找,插入,刪除的實驗筆記1(計算機軟件基礎)

一、實驗目的和要求
目的:

  • 熟悉單鏈表的創建,取值,查找,插入,刪除等操作。

要求:

  1. 初始化單鏈表La
  2. 在La中插入一個新結點
  3. 刪除La中某個結點

二、實驗內容
(1)單鏈表中插入結點
插入結點有兩種方法,一種頭插,一種尾插
頭插法:從空表開始,重複讀入數據,生成新結點,將讀入的數據存放到新結點的數據域中,然後將新結點插入到當前鏈表的頭結點之後,直至讀入結束標誌爲止,頭插法創建鏈表的根本在於最後兩條語句:

node->next = head->next;
//將頭指針所指向的下一個結點的地址,賦給新創建結點的next
head->next= node;
//將新創建的結點的地址賦給頭指針的下一個結點

在這裏插入圖片描述
尾插法:將新結點插到當前單鏈表的表尾處

end->next = node;
//將新開闢的node的地址賦給head的下一個結點地址
end = node;
//將新建的結點node的地址賦給尾結點end

(2)單鏈表中刪除結點

ListDelete (&L, i, &e):刪除單鏈表L的第i個結點,將結點元素值賦給e。

利用循環操作將p指針定位到第i-1個元素位置,用q指針指向第i個結點 位置並將元素值賦給e,讓第i-1個元素的指針域指向第i+1個元素,然後 釋放q結點;單鏈表的刪除標準語句序列爲:

  1. q = p->next;
  2. p->next = q->next;
  3. e = q->data;

三、依據的基本原理
整個程序的流程看主函數,具體函數實現過程請看第四點,爲方便講解,我直接在代碼後通過註釋的方式講解原理:

int main(int argc, int argv[])  #定義主函數
{
	int opt = 0; #定義變量opt
	int num = 0; #定義變量num
	//創建鏈表
	printf("請創建一個鏈表:\n");
	pNode phead = create_list(); #運行自定義的創建鏈表函數
	//打印輸出鏈表
	printf("打印輸出鏈表:\n");
	traverse_list(phead); #運行自定義的輸出鏈表函數
	
	//在數字key前邊插入數字data
	int key; #定義變量key
	int data; #定義變量data
	Node node;
	printf("在數字幾前插入:\n");
	scanf("%d",&data); #輸入
	printf("輸入你想要插入的數字:\n");
	scanf("%d",&key); #輸入想插入的數字
	insertnode_bypre(phead,node,key,data); #運行自定義的插入函數
	traverse_list(phead);  #運行自定義的輸出鏈表函數
	
	//在數字key1後邊插入數字data1
	int key1;
	int data1; #定義變量
	Node node1;
	printf("在數字幾後插入:\n");
	scanf("%d",&data1);
	printf("輸入你想要插入的數字:\n");
	scanf("%d",&key1);
	insertnode_byback(phead,node,key1,data1); #後插法
	traverse_list(phead); #運行自定義的輸出鏈表函數
	
	//刪除節點
	int deldata;
	printf("刪除數字:\n");
	scanf("%d",&deldata);
	deletenode(phead, deldata); #運行自定義的刪除結點函數
	traverse_list(phead); #運行自定義的輸出鏈表函數
	
	//查找數字,輸出位置
	printf("輸入想要查找的數字:\n");
	scanf("%d",&num);
	searchnode(phead,num); #運行自定義的按值查找函數
	return 0;
}

總的來說,該程序先創建一個鏈表,用戶可根據需要選擇創建的鏈表長度,並給鏈表賦值,創建成功後,輸出鏈表.

然後分別使用前插法與後插法插入數據隨後刪除數據.

最後查找某個數據所在的位置.至此,程序結束.

四、實驗步驟
這是一個用結構體寫的程序,拆開,會很好理解.

程序一開始,就用結構體定義結點,把struct Node *定義爲新類型pNode,是一個結構體的指針。隨後,自定義了7個函數,分別是初始化一個鏈表結點, 創建鏈表函數, 遍歷鏈表, 按值查找操作, 前插法, 後插法, 刪除結點.

爲了便於讀者理解,我還是通過註釋的方式進行講解:

//(1)初始化一個鏈表結點
pNode init_node(Node *pnode, int data)
{
	pnode = (Node *)malloc(sizeof(Node));
	pnode -> data = data;//初始化數字域
	pnode -> next = NULL;//初始化指針域
	return pnode;
}
//創建鏈表函數
pNode create_list()
{
	int i;  //    用於下面循環
	int len;  //    用來存放有效節點的字數
	int val;  //    用於臨時存放用戶輸入的數據
	pNode pHead = (pNode)malloc(sizeof(Node)); // 分配一個不存放有效數據的頭結點
	pNode pTail = pHead;   //鏈表的最後一個節點
	pTail->next = NULL;   //    最後一個節點的指針置爲空
	printf("請輸入節點個數:");
	scanf("%d", &len);
	for (i = 0; i < len; i++)
	{
		printf("第 %d 個節點的數值:", i + 1);
		scanf("%d", &val);
		pNode pNew = (pNode)malloc(sizeof(Node));    //爲節點分配空間	
		//將用戶輸入的數據賦給節點的成員,將最後一個節點的指針指向
		//下一個新的節點,將新節點中的指針置爲空,將新節點賦給最後的一個節點
		pNew -> data = val;   //將用戶輸入的數據賦給節點的成員
		pTail -> next = pNew; //將最後一個節點的指針指向下一個新的節點
		pNew -> next = NULL; //將新節點中的指針置爲空
		pTail = pNew;  //將新節點賦給最後的一個節點
		printf("successful!");	
	}
	return pHead; //返回頭節點
}
//(2)在鏈表中插入一個新結點。
//前插法
pNode insertnode_bypre(Node *phead, Node node,int data,int key)
{
	Node *pnode = init_node(&node, data);//初始化插入的結點
	Node *ptmp = phead;
	
	if (phead == NULL)//鏈表爲空,直接返回初始化的值
	{
		return pnode;
	}
	else if (phead->data == key)//處理的第一個結點是否爲目標結點
	{
		phead = pnode;
		pnode->next = ptmp;
	}
	else
	{
		while((ptmp->next != NULL) && (ptmp->next->data != key))
		{
			ptmp = ptmp->next;
		}
		if (ptmp->next == NULL)//沒有找到的情況
		{
			printf("insert key NOT FOUND\n");
		}
		else//把新結點插入到目標結點的前面
		{
			ptmp = (Node *)malloc(sizeof(Node));  //分配一個Node類型大小的內存空間,並把分配空間的首地址強制轉換成Node *類型的
			ptmp->data = data;  //  爲新結點的數據域賦值
            ptmp->next = phead->next; //  將頭指針所指向的下一個結點的地址,賦給新創建結點的next 
            phead->next = ptmp; //  將新創建的結點的地址賦給頭指針的下一個結點
		}
	}
	printf("successful!");
	return phead;
}
//後插法
pNode insertnode_byback(Node *phead,Node node ,int data,int key)
{
	Node *pnode = init_node(&node, data);//初始化插入的結點
	Node *ptmp = searchnode(phead,key);//查找目標結點
	
	if (ptmp == NULL)//鏈表爲空,或者沒有找到
	{
		printf("Link is empty or not found key!\n");
		return phead;
	}
	if (ptmp->next == NULL)//如果key爲最後一個結點
	{
		ptmp->next = pnode;
	}
	else//將新結點插入到目標結點的後面
	{
		ptmp = (Node *)malloc(sizeof(Node)); //分配一個Node類型大小的內存空間,並把分配空間的首地址強制轉換成Node *類型的
		ptmp -> next = NULL;  //  初始化頭結點指向的下一個地址爲 NULL
		phead -> next = ptmp;
		phead = phead->next;
	}
	printf("successful!");
	return phead;
}
// (3)刪除鏈表中的某一個結點。
pNode deletenode(Node *phead, int key)
{
	Node *ptmp = phead;
	Node *tmp = NULL;
	
	if (phead == NULL)//處理鏈表爲空的情況
	{
		printf("Link is empty,delete fail!\n");
		return NULL;
	}
	else if(phead->data == key)//單獨處理第一個結點
	{
		phead = phead->next;
		free(ptmp); //釋放目標結點
		ptmp = NULL;
	}
	else
	{
		while (ptmp->next != NULL && ptmp->next->data != key)//沒找&&沒有找到
		{
			ptmp = ptmp->next;
		}
		if (ptmp->next == NULL)//沒有找到
		{
			printf("delete key is not found!\n");
			return phead;
		}
		if (ptmp->next->data == key)//找到目標結點並刪除
		{
			tmp = ptmp->next;
            ptmp->next = tmp->next;
			free(tmp); //釋放目標結點
			tmp = NULL; 
		}
	}
	printf("successful!");
	return phead;
}
// (4)在鏈表中查找某結點並返回其位置。
pNode searchnode(Node *phead,int key)
{
	Node *ptmp = phead;
	int i = 0;
	if (ptmp == NULL) //查找結點,判斷該結點是否存在
	{
		return NULL;
	}
	
	while (ptmp->data != key && ptmp->next != NULL)
	{	
		i=i+1;
		ptmp = ptmp->next;
	}
	
	if (ptmp -> data == key)
	{	
		printf("所在位置爲:%d\n",i);
		return 0;
	}
	if (ptmp->next == NULL)
	{
		printf("該數字不在鏈表中\n");
		return NULL;
	}
}
//(5)打印輸出鏈表中的結點元素值。
void traverse_list(pNode pHead)
{
	pNode p = pHead->next;   //將頭節點的指針給予臨時節點p
	while (NULL != p)  //節點p不爲空,循環
	{
		printf("%d ", p->data);
		p = p->next;
	}
	printf("\n");
}

五、實驗結果及分析
在這裏插入圖片描述
六、附錄(程序源碼)

#include <stdio.h>
#include <stdlib.h>

typedef struct node{ //用結構體定義結點
	int data;
	struct node *next;
}Node, *pNode; //把struct Node *定義爲新類型pNode,是一個結構體的指針。  

//初始化一個鏈表結點
pNode init_node(Node *pnode, int data);
//創建鏈表函數
pNode create_list();
//遍歷鏈表
void traverse_list(pNode pHead);
//按值查找操作
pNode searchnode(Node *phead, int key);
//前插法
pNode insertnode_bypre(Node *phead, Node node, int data, int key);
//後插法
pNode insertnode_byback(Node *phead, Node node, int data, int key);
//刪除結點
pNode deletenode(Node *phead, int key);


//(1)初始化一個鏈表結點
pNode init_node(Node *pnode, int data)
{
	pnode = (Node *)malloc(sizeof(Node));
	pnode -> data = data;//初始化數字域
	pnode -> next = NULL;//初始化指針域
	
	return pnode;
}

//創建鏈表函數
pNode create_list()
{
	int i;  //    用於下面循環
	int len;  //    用來存放有效節點的字數
	int val;  //    用於臨時存放用戶輸入的數據
	pNode pHead = (pNode)malloc(sizeof(Node)); // 分配一個不存放有效數據的頭結點
	pNode pTail = pHead;   //鏈表的最後一個節點
	pTail->next = NULL;   //    最後一個節點的指針置爲空
	printf("請輸入節點個數:");
	scanf("%d", &len);
	for (i = 0; i < len; i++)
	{
		printf("第 %d 個節點的數值:", i + 1);
		scanf("%d", &val);
		pNode pNew = (pNode)malloc(sizeof(Node));    //爲節點分配空間
		
		//補充代碼,將用戶輸入的數據賦給節點的成員,將最後一個節點的指針指向
		//下一個新的節點,將新節點中的指針置爲空,將新節點賦給最後的一個節點
		pNew -> data = val;   //將用戶輸入的數據賦給節點的成員
		pTail -> next = pNew; //將最後一個節點的指針指向下一個新的節點
		pNew -> next = NULL; //將新節點中的指針置爲空
		pTail = pNew;  //將新節點賦給最後的一個節點
		printf("successful!");	
	}
	return pHead; //返回頭節點
	
}

//(2)在鏈表中插入一個新結點。
//前插法
pNode insertnode_bypre(Node *phead, Node node,int data,int key)
{
	Node *pnode = init_node(&node, data);//初始化插入的結點
	Node *ptmp = phead;
	
	if (phead == NULL)//鏈表爲空,直接返回初始化的值
	{
		return pnode;
	}
	else if (phead->data == key)//處理的第一個結點是否爲目標結點
	{
		phead = pnode;
		pnode->next = ptmp;
	}
	else
	{
		while((ptmp->next != NULL) && (ptmp->next->data != key))
		{
			ptmp = ptmp->next;
		}
		if (ptmp->next == NULL)//沒有找到的情況
		{
			printf("insert key NOT FOUND\n");
		}
		else//把新結點插入到目標結點的前面
		{
			ptmp = (Node *)malloc(sizeof(Node));  //分配一個Node類型大小的內存空間,並把分配空間的首地址強制轉換成Node *類型的
			ptmp->data = data;  //  爲新結點的數據域賦值
            ptmp->next = phead->next; //  將頭指針所指向的下一個結點的地址,賦給新創建結點的next 
            phead->next = ptmp; //  將新創建的結點的地址賦給頭指針的下一個結點
		}
	}
	printf("successful!");
	return phead;
}

//後插法
pNode insertnode_byback(Node *phead,Node node ,int data,int key)
{
	Node *pnode = init_node(&node, data);//初始化插入的結點
	Node *ptmp = searchnode(phead,key);//查找目標結點
	
	if (ptmp == NULL)//鏈表爲空,或者沒有找到
	{
		printf("Link is empty or not found key!\n");
		return phead;
	}
	if (ptmp->next == NULL)//如果key爲最後一個結點
	{
		ptmp->next = pnode;
	}
	else//將新結點插入到目標結點的後面
	{
		ptmp = (Node *)malloc(sizeof(Node)); //分配一個Node類型大小的內存空間,並把分配空間的首地址強制轉換成Node *類型的
		ptmp -> next = NULL;  //  初始化頭結點指向的下一個地址爲 NULL
		phead -> next = ptmp;
		phead = phead->next;
	}
	printf("successful!");
	return phead;
}

// (3)刪除鏈表中的某一個結點。
pNode deletenode(Node *phead, int key)
{
	Node *ptmp = phead;
	Node *tmp = NULL;
	
	if (phead == NULL)//處理鏈表爲空的情況
	{
		printf("Link is empty,delete fail!\n");
		return NULL;
	}
	else if(phead->data == key)//單獨處理第一個結點
	{
		phead = phead->next;
		free(ptmp); //釋放目標結點
		ptmp = NULL;
	}
	else
	{
		while (ptmp->next != NULL && ptmp->next->data != key)//沒找&&沒有找到
		{
			ptmp = ptmp->next;
		}
		if (ptmp->next == NULL)//沒有找到
		{
			printf("delete key is not found!\n");
			return phead;
		}
		if (ptmp->next->data == key)//找到目標結點並刪除
		{
			tmp = ptmp->next;
            ptmp->next = tmp->next;
			free(tmp); //釋放目標結點
			tmp = NULL; 
		}
	}
	printf("successful!");
	return phead;
}


// (4)在鏈表中查找某結點並返回其位置。
pNode searchnode(Node *phead,int key)
{
	Node *ptmp = phead;
	int i = 0;
	if (ptmp == NULL) //查找結點,判斷該結點是否存在
	{
		return NULL;
	}
	
	while (ptmp->data != key && ptmp->next != NULL)
	{	
		i=i+1;
		ptmp = ptmp->next;
	}
	
	if (ptmp -> data == key)
	{	
		printf("所在位置爲:%d\n",i);
		return 0;
	}
	if (ptmp->next == NULL)
	{
		printf("該數字不在鏈表中\n");
		return NULL;
	}
}

//(5)打印輸出鏈表中的結點元素值。
void traverse_list(pNode pHead)
{
	pNode p = pHead->next;   //將頭節點的指針給予臨時節點p
	while (NULL != p)  //節點p不爲空,循環
	{
		printf("%d ", p->data);
		p = p->next;
	}
	printf("\n");
}


//主函數
int main(int argc, int argv[])
{
	int opt = 0;
	int num = 0;
	//創建鏈表
	printf("請創建一個鏈表:\n");
	pNode phead = create_list();
	//打印輸出鏈表
	printf("打印輸出鏈表:\n");
	traverse_list(phead);
	
	//在數字key前邊插入數字data
	int key;
	int data;
	Node node;
	printf("在數字幾前插入:\n");
	scanf("%d",&data);
	printf("輸入你想要插入的數字:\n");
	scanf("%d",&key);
	insertnode_bypre(phead,node,key,data);
	traverse_list(phead);
	
	//在數字key1後邊插入數字data1
	int key1;
	int data1;
	Node node1;
	printf("在數字幾後插入:\n");
	scanf("%d",&data1);
	printf("輸入你想要插入的數字:\n");
	scanf("%d",&key1);
	insertnode_byback(phead,node,key1,data1);
	traverse_list(phead);
	
	//刪除節點
	int deldata;
	printf("刪除數字:\n");
	scanf("%d",&deldata);
	deletenode(phead, deldata);
	traverse_list(phead);
	
	//查找數字,輸出位置
	printf("輸入想要查找的數字:\n");
	scanf("%d",&num);
	searchnode(phead,num);
	return 0;
}

以上就是全部內容,如果大家有更好的方法,歡迎大家與我討論
在這裏插入圖片描述

發佈了40 篇原創文章 · 獲贊 77 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章