1. 程式人生 > >連結串列的學習—帶頭結點單向連結串列的逆置

連結串列的學習—帶頭結點單向連結串列的逆置

一個單向的連結串列,實現它的逆置並不難,我在網上看到了其中的一種演算法,叫做就地逆置,它的實現思路讓我花了好久的時間才理解清楚。。。(可能是我太笨了吧,敲打)
下面的程式碼從頭到尾,展現了帶頭結點連結串列的初始化、建立、展示、逆置的過程。使用語言為標準C

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

typedef int Status;	//函式狀態型別

typedef int ElemType;	//元素型別

typedef struct node{
	ElemType data;
	struct node *next;
}Node,*LinkList;//結點型別

Status InitList(LinkList *L);
Status CreatList(LinkList L,int n);
Status DisplayList(LinkList L);
Status Reverse(LinkList L);

int main(void)
{
	LinkList L;
	int L_Length;
	InitList(&L);//初始化連結串列
	printf("請輸入單鏈表的長度:\n");
	scanf("%d",&L_Length);
	if(L_Length<1)
		exit(-1);//長度不符合要求
	printf("請依次輸入各個元素的值:\n");
	CreatList(L,L_Length);
	DisplayList(L);
	Reverse2(L);
	printf("After reverseing!\n");
	DisplayList(L);
	return 0;
}
//初始化一個連結串列
Status InitList(LinkList *L)
{
	*L = (LinkList)malloc(sizeof(node));
	if(!(*L))
		exit(-2);
	return 1;
}
//在初始化的基礎上按順序建立一個連結串列
Status CreatList(LinkList L,int n)
{
	LinkList p = L;
	int i;
	for(i=0;i<n;i++)
	{
		(p->next) = (LinkList)malloc(sizeof(node));
		if(!(p->next))
			exit(-2);
		scanf("%d",&p->next->data);
		p = p ->next;
	}
	p->next = NULL;
	return 1;
}
//依次輸出單鏈表中的各個元素
Status DisplayList(LinkList L)
{
	LinkList p;
	p = L->next;
	while(p)
	{
		printf("%-5d",p->data);
		p = p->next;
	}
	printf("\n");
	return 1;
}

//逆置 (就地逆置)

Status Reverse(LinkList L)
{
	LinkList last = L->next;
	LinkList first;
	while(last->next)
	{
		first = L->next;
		L->next = last->next;
		last->next = L->next->next;
		L->next->next = first;
	}
	return 1;
}


我當時在分析這個逆置函式Reverse()時發生困難,按照我的思路,會寫出這樣的逆置函式:
Status Reverse(LinkList L)
{
	LinkList p = L->next;
	LinkList q = L->next->next;
	LinkList t = NULL;
	while(q != NULL)
	{
		t = q->next;
		q->next = p;
		p=q;
		q = t;
	}
	L->next->next = NULL;//設定連結串列尾
	L->next = p;			//修改連結串列頭
	return 1;
}
我的思路可以按照下邊的示意圖來理解(花了半天畫這個圖,動手能力待加強啊!):


為了理解原先的逆置函式:

//逆置 (就地逆置)
Status Reverse(LinkList L)
{
	LinkList last = L->next;
	LinkList first;
	while(last->next)
	{
		first = L->next;
		L->next = last->next;
		last->next = L->next->next;
		L->next->next = first;
	}
	return 1;
}
我畫出下邊這個圖,注意節點的連線關係每次迴圈first和last指向的節點都在變,終於完全的理解了,開心!我畫了這兩個圖作為學習的筆記!連結串列的逆置必須畫圖才能更好的理解!