1. 程式人生 > >連結串列初解(一)——單鏈表的建立、刪除、插入、測長、排序、逆置

連結串列初解(一)——單鏈表的建立、刪除、插入、測長、排序、逆置

由於考試需要,複習一下單鏈表的各種常見操作,直接上程式碼+註釋,需要的可以參考下哈~

Code:

#include<iostream>
using namespace std;

typedef struct student
{
	int data;
	struct student *next;
}node;

//建立單鏈表
node *create()
{
	node *head, *p, *s;
	int x;
	head = (node *)malloc(sizeof(node));	//先建立一個頭節點,便於頭指標的操作。
	p = head;
	printf("\nInput the data (end with '0') : ");
	while(1)
	{
		if(scanf("%d", &x) != EOF && x != 0)
		{//如果輸入資料合法,則再建立一個節點;否則跳出迴圈。
			s = (node *)malloc(sizeof(node));
			s->data = x;
			p->next = s;
			p = s;
		}
		else break;
	}
	head = head->next;
	p->next = NULL;
	return head;
}

//計算單鏈表長度
int length(node *head)
{
	int n = 0;
	while(head != NULL)
	{
		head = head->next;
		n++;
	}
	return n;
}

//列印單鏈表
void print(node *head)
{
	int n = length(head);
	printf("Output the list (%d records~) : ", n);
	while(head != NULL)
	{
		printf(head->next == NULL ? "%d\n" : "%d->", head->data);
		head = head->next;
	}
}

//刪除單鏈表節點
node *del(node *head, int num)
{
	node *p1, *p2;
	if(head == NULL) return NULL;
	p1 = head;
	while(num != p1->data && p1->next != NULL)
	{//若當前指標所儲存的值與要刪除的值不符,則向後遍歷,直至相等或至最後一個節點。
		p2 = p1;
		p1 = p1->next;
	}
	if(num == p1->data)
	{//如果連結串列中存在要刪除的節點,則分兩種情況:在頭節點處或連結串列中。
		if(head == p1) head = p1->next;
		else p2->next = p1->next;
		free(p1);	//別忘了釋放刪除的節點哦~節約點~
	}
	else printf("There is no '%d' \n", num);	//找不到要刪除的值。
	return head;
}

//插入單鏈表節點
node *insert(node *head, int num)
{
	node *p1, *p2, *p3;
	p2 = head;
	p1 = (node *)malloc(sizeof(node));	//先將要插入的節點申請下~
	p1->data = num;
	//思路同刪除節點操作
	while(num > p2->data && p2->next != NULL) 
	{
		p3 = p2;
		p2 = p2->next;
	}
	if(num <= p2->data)
	{
		if(head == p2)
		{
			p1->next = p2;
			head = p1;
		}
		else
		{
			p3->next = p1;
			p1->next = p2;
		}
	}
	else 
	{//此處要細心,別忘了可以在尾部插入節點。
		p2->next = p1;
		p1->next = NULL;
	}
	return head;
}

//單鏈表排序
node *sort(node *head)
{
	node *p;
	p = head;
	int n, temp;
	n = length(head);
	//運用氣泡排序似乎對連結串列排序來說是最方便的~(遞增)
	for(int j = 1; j < n; j++)
	{
		p = head;
		for(int i = 0; i < n - j; i++)
		{
			if(p->data > p->next->data)
			{
				temp = p->data;
				p->data = p->next->data;
				p->next->data = temp;
			}
			p = p->next;
		}
	}
	printf("\nAfter sorting ~\n");
	return head;
}

//單鏈表逆置
node *reverse(node *head)
{
	node *p1, *p2, *p3;
	p1 = head;
	p2 = p1->next;
	if(head == NULL || head->next == NULL) return head;
	//逆置的思想:選出三個節點(第三個可能是NULL),操作前兩個節點,使其逆置,而後按同樣做法操作第二、三個節點和第四個節點~
	while(p2 != NULL)
	{
		p3 = p2->next;
		p2->next = p1;
		p1 = p2;
		p2 = p3;
	}
	head->next = NULL;
	head = p1;
	printf("\nAfter reversing ~\n");
	return head;
}

int main()
{
	node *head;
	//建立單鏈表
	head = create();
	print(head);
	//排序
	head = sort(head);
	print(head);
	//刪除單鏈表
	int numD;
	printf("\nInput the value you want to delete : ");
	scanf("%d", &numD);
	head = del(head, numD);
	print(head);
	//插入單鏈表
	int numS;
	printf("\nInput the value you want to insert : ");
	scanf("%d", &numS);
	head = insert(head, numS);
	print(head);
	//逆置
	head = reverse(head);
	print(head);

	return 0;
}
執行示例:

Ps:僅供參考哈~