鏈表的基礎操作總結(鏈表創建,插入,刪除,遍歷等等)


直接上代碼吧,感覺注釋還可以,應該可以看的懂。。不懂的話。。

就再看看吧。。。

 

// 數據結構基礎--鏈表的創建及鏈表基本操作

#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 creat_list(void) ;                              // 創建鏈表
void traverse_list(PNODE phead) ;					  // 遍歷輸出鏈表
bool is_empty(PNODE pHead) ;						  // 判斷鏈表是否為空
int length_list(PNODE pHead) ;						  // 求鏈表長度
bool insert_list(PNODE pHead, int pos, int val) ;	  // 插入鏈表元素
bool delete_list(PNODE pHead, int pos, int *) ;		  // 刪除鏈表元素
void sort_list(PNODE pHead) ;						  // 對鏈表進行排序

/**********************************/
// 主函數
/**********************************/
int main()
{
	PNODE pHead = NULL ;  // 等價於struct Node* pHead = NULL ;
	int val, pos, ele ;
	
	pHead = creat_list() ; // creat_list(), 創建一個非循環鏈表
	
	if (is_empty(pHead))
	{
		printf("鏈表為空!長度為0 。\n") ;
	} 
	else
	{
		printf("鏈表不為空!其長度為%d。\n\n", length_list(pHead)) ;
		printf("您所創建的鏈表是:\n") ;
		traverse_list(pHead) ;  // 遍歷該鏈表
		printf("\n") ;
	}
	
	
	printf("對該鏈表從大到小排序后為:\n") ;
	sort_list(pHead) ;
	traverse_list(pHead) ;
	
	printf("\n您是否要對該鏈表插入元素:(y/n) \n") ;
	char ch;
	printf("Please enter:") ;
	getchar() ;
	scanf("%c" , &ch) ;
	printf("%c\n", ch) ;
	if (ch == 89 || ch == 121)
	{
		printf("輸入您要插入的元素及位置(以逗號隔開):") ;
		scanf("%d,%d", &pos, &ele) ;
		insert_list(pHead, pos, ele) ;
		printf("插入元素后該鏈表為:\n") ;
		traverse_list(pHead) ;
	} 
	else
	{
		printf("您選擇不插入數據!") ;
	}

	
	printf("\n請輸入您要刪除的元素位置:\n") ;
	scanf("%d", &pos) ;
	if (delete_list(pHead, pos, &val))
	{
		printf("刪除成功,您刪除的元素是%d。\n", val) ;
		printf("刪除后的鏈表為:\n") ;
		traverse_list(pHead) ;
	}
	
	return 0 ;
}


/**********************************/
// 創建鏈表調用函數
/**********************************/
PNODE creat_list(void)           // 該函數為PNODE類型的,即是其返回值PNODE類型的,即是一個地址
{
	int len ;  // 用來存放有效節點的初始個數
	int i ;
	int val ;  // 用來臨時存放用戶輸入的節點的值
	
	PNODE pHead = (PNODE) malloc(sizeof(NODE)) ;   // 分配內存空間,創建鏈表
	if ( pHead == NULL)
	{
		printf("內存分配失敗,程序將終止!\n") ;
		exit(-1) ;
	}
	
	PNODE pTail = pHead ;
	pTail ->pNext = NULL ;
	
	printf("請輸入您要生成的鏈表節點數:len=") ;
	scanf("%d" , &len) ;
	
	for (i = 0; i<len; ++ i)
	{
		printf("請輸入第%d個節點值:", i+1) ;
		scanf("%d", &val) ; 
		printf("\n") ;
		
		PNODE pNew = (PNODE) malloc(sizeof(NODE)) ;   // 增加節點,分配內存
		if ( NULL == pNew)
		{
			printf("內存分配失敗,程序將終止!\n") ;
			exit(-1) ;
		}
		pNew ->data = val ; //
		pTail ->pNext = pNew ;
		pNew ->pNext = NULL ;
		pTail = pNew ;
	}
	return pHead ;
}

/**********************************/
// 遍歷鏈表調用函數
/**********************************/
void traverse_list(PNODE phead)
{
	PNODE p = phead->pNext ;
	while (p != NULL)
	{
		printf("%d\t", p->data) ;
		p = p->pNext ;
	}
	printf("\n") ;
	
}

/**********************************/
// 判斷鏈表是否為空調用函數
/**********************************/
bool is_empty(PNODE pHead)
{
	if ( pHead->pNext == NULL)    // 頭結點指針域為空,則鏈表為空
	{
		return true ;
	} 
	else
	{
		return false ;
	}
}

/**********************************/
// 求鏈表長度調用函數
/**********************************/
int length_list(PNODE pHead)
{
	int len = 0 ;
	PNODE p = pHead ->pNext ;
	while ( p != NULL)
	{
		++ len ;
		p = p->pNext ;
	}
	return len ;
}

/**********************************/
// 對鏈表排序調用函數--從大到小
/**********************************/
void sort_list(PNODE pHead)
{
	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 ;
}

/**********************************/
// 對鏈表插入元素調用函數
/**********************************/
/*
插入元素的原理:
if you want to insert an element to this 鏈表。The first thing you have to do is 把這個要插入的位置騰出來。
即是必須創建一個新的鏈表元素,而且是自由的鏈表元素---等待安排。
並且有一個新的鏈表指針,指向(如何使其指向亦是一個值得思考的問題)要插入的位置的前面---監視該位置,留待后用。
然后,用你所創建那個自由的鏈表元素插入。
插入的前提是將目標鏈表截成兩端--從要插入的位置前面截斷,最后用掛靠的方式鏈接即可。
其原理是---p->next 所代表的是一個地址,也可以認為是下一個鏈表元素
關於自由鏈表元素--其data域用於存儲要插入的元素值。
此時還需要創建一個臨時的鏈表元素,用於臨時存儲地址。

  具體如下:
  pNew -> data = val ;   // 自由元素數據域
  PNODE q = p->next ;    // 臨時元素存儲pos位置的地址
  p->next = pNew ;       // 將自由元素的地址賦值給監視元素的地址域--掛到監視元素后面
  pNew->next = q ;       // 將臨時元素--即是原來pos位置元素    的地址賦值給自由元素--掛到自由元素后面
  
	此時就完成整個鏈接--將插入的元素掛到其前面的那個元素后面,再將原來后半部分的元素掛到新插入的元素后面
	
*/
bool insert_list(PNODE pHead, int pos, int val)
{
	int i = 0 ;
	PNODE p = pHead ;
	
	while(p != NULL && i<pos-1)
	{
		p = p->pNext ;
		++i ;
	}
	
	if (i>pos-1 || p==NULL)
	{
		return false ;
	}
	
	PNODE pNew = (PNODE)malloc(sizeof(NODE)) ;
	if (pNew == NULL)
	{
		printf("動態內存分配失敗!") ;
		exit(-1) ;
	}
	pNew -> data = val ;   // 自由元素數據域
	PNODE q = p->pNext ;    // 臨時元素存儲pos位置的地址
	p->pNext = pNew ;       // 將自由元素的地址賦值給監視元素的地址域--掛到監視元素后面
	pNew->pNext = q ;       // 將臨時元素--即是原來pos位置元素的地址賦值給自由元素--掛到自由元素后面
	// 此時完成鏈表的重新鏈接
	return true ;
	
}

/**********************************/
// 對鏈表刪除元素調用函數
/**********************************/
bool delete_list(PNODE pHead, int pos, int *val) 
{
	int i = 0 ;
	PNODE p = pHead ;
	
	while(p->pNext != NULL && i<pos-1)
	{
		p = p->pNext ;
		++i ;
	}
	
	if (i>pos-1 || p->pNext==NULL)
	{
		return false ;
	}
	
	PNODE q = p->pNext ;
	*val = q->data ;
	
	p->pNext = p->pNext->pNext ;
	free(q) ;               // 釋放內存!!!
	q=NULL ;
	
	return true ;
}

  


免責聲明!

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



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