1. 程式人生 > >單鏈表的 C 語言實現

單鏈表的 C 語言實現

用 C 語言實現一個單鏈表,包含連結串列的建立、遍歷、插入、刪除、排序等常用操作

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

struct Node
{
	int data;//資料域
	struct Node * pNext;//指標域,存放下一個節點的地址
};

//函式宣告
struct Node * createList(void);//建立連結串列
void traverseList(struct Node * pHead);//遍歷輸出連結串列
bool isEmptyList(struct Node * pHead);//判斷連結串列是否為空
int size(struct Node * pHead);//連結串列長度
void sortList(struct Node * pHead);//連結串列排序
bool deleteList(struct Node * pHead, int pos, int * pVal);//刪除連結串列的節點
bool insertList(struct Node * pHead, int pos, int val);//增加一連結串列節點

int main(void)
{
	int deleteValue;//被刪除的值 
	struct Node * pHead = NULL;
	//建立連結串列
	pHead = createList();
	if (NULL == pHead)
	{
		printf("連結串列分配記憶體失敗\n");
		exit(-1);
	}
	
	//遍歷輸出連結串列
	traverseList(pHead);
	
	if(insertList(pHead,4,88))
	{
		printf("為連結串列新增了一個值\n");
		traverseList(pHead);
	}
	
	if(deleteList(pHead,3,&deleteValue))
	{
		printf("刪除了連結串列中的一個值 %d \n",deleteValue);
		traverseList(pHead);
	}
	else
	{
		printf("刪除失敗,沒有這個值");
	}	
	
//	if(isEmptyList(pHead))
//	{
//		printf("連結串列為空\n");
//	}
//	else
//	{
//		printf("連結串列不為空\n");
//	}

//	int length = size(pHead);
//	printf("連結串列的長度是%d ",length);
	
//	sortList(pHead);
//	printf("排序後的陣列\n");
//	traverseList(pHead);
	
	return 0;
}
struct Node * createList()
{
	int i;
	int len;
	int val;
	struct Node * pHead = (struct Node *)malloc(sizeof(struct Node));
	if (NULL == pHead)
	{
		printf("連結串列分配記憶體失敗,程式終止!\n");
		exit(-1);
	}
	
	struct Node * pTail = pHead;//定義一個指標,永遠指向尾節點,初始時刻,pTail和pHead同時指向頭結點
	pTail->pNext = NULL;//初始時刻,頭結點也是最後一個節點,指標域應為空
	
	printf("請輸入需要建立的連結串列的長度:len= ");
	scanf("%d", &len);
	
	for (i=0; i<len; i++)//生成len個有效節點 
	{
		printf("請輸入第%d個節點的值:",i+1);
		scanf("%d",&val);
		
		//每一次迴圈建立一個節點,並把指標儲存在pNode指標變數中
		struct Node * pNode = (struct Node *)malloc(sizeof(struct Node));
		if (NULL == pNode)
		{
			printf("建立連結串列失敗,程式終止!\n");
			exit(-1);
		}
		pNode->data = val;//填充資料域
		pTail->pNext = pNode;//pTail指向的那個節點的指標域儲存新建立的節點的地址
		pTail = pNode;//pTail儲存新建立的節點的地址,這樣可以保證pTail永遠指向最後一個節點
		pNode->pNext = NULL;//最後一個節點的指標域置為空
	}

	return pHead;
}

void traverseList(struct Node * pHead)
{
	
	//方法一:先定義一個指標指向第一個節點,依次迴圈,看看這個指標所指向的節點的指標域是否為空,如果為空,則遍歷到最後了
//	struct Node * p = pHead->pNext;//這樣p就儲存了首節點的地址,也就指向了第一個節點
//	while(p != NULL)
//	{
//		printf("%d ",p->data);
//		p = p->pNext;//指標往下移一個節點
//	}
//	printf("\n");

	//方法二:或者直接用pHead指標迴圈也可以 
	while(pHead->pNext != NULL)
	{
		printf("%d ",pHead->pNext->data);
		pHead = pHead->pNext;
	}
	printf("\n");
	
	return ;
}
bool isEmptyList(struct Node * pHead)
{
	if(pHead->pNext == NULL)//pHead指標指向頭結點,頭結點的指標域為空,連結串列也就為空 
	{
		return true;//為空
	}
	else
	{
		return false;
	}
}
int size(struct Node * pHead)
{
	int len;
	if(isEmptyList(pHead))
	{
		len= 0;
		return len;
	}
	while(pHead->pNext != NULL)
	{
		len++;
		pHead = pHead->pNext;
	}
	return len;
}
void sortList(struct Node * pHead)
{
	int i,j,tmp;
	struct Node * p;//定義一前一後兩個指標 
	struct Node * q;
	int length = size(pHead);
	//類比陣列的氣泡排序 
	for (i=0,p=pHead->pNext; i<length-1; i++,p=p->pNext)
	{
		for (j=i+1,q=p->pNext; j<length; j++,q=q->pNext)
		{
			if(p->data > q->data)
			{
				tmp = p->data;
				p->data = q->data;
				q->data = tmp;
			} 
		}
	}
}
bool insertList(struct Node * pHead, int pos, int val)
{
	struct Node * p = pHead;
	int i = 0;
	//執行完while語句,此時的p已經指向了pos前的一個節點 
	while (NULL != p && i<pos-1)
	{
		p = p->pNext;
		i++;
	}
	if (i>pos-1 || NULL ==p)
	{
		return false;
	}
	struct Node * pNew = (struct Node *)malloc(sizeof(struct Node));
	if (NULL == pNew)
	{
		printf("分配記憶體失敗,建立節點失敗\n"); 
		exit(-1);
	}
	pNew->data = val;//為新節點資料域賦值
	//如下兩行插入新節點 
	pNew->pNext = p->pNext;
	p->pNext = pNew;
	//或者用下面定義個臨時指標變數的方式 
//	struct Node * q = p->pNext;
//	p->pNext = pNew;
//	pNew->pNext = q 
	
	return true; 
}

bool deleteList(struct Node * pHead, int pos, int * pVal)
{
	struct Node * p = pHead;
	int i = 0;
	while (NULL != p->pNext && i<pos-1)
	{
		p = p->pNext;
		i++;
	}
	if (i>pos-1 || NULL ==p->pNext)
	{
		return false;
	}
	*pVal = p->data;//儲存刪除的值,傳遞到主函式中,以備檢視 
	p->pNext = p->pNext->pNext;
	
	//或者用下面定義個臨時指標變數的方式 
//	struct Node * q = p->pNext;
//	*pVal = q->data;
//	 p->pNext = p->pNext->pNext;
//	 free(q);
//	 q = NULL;
	
	return true;
}