線性表單鏈表實現基礎操作和效果圖

2020-08-07 20:57:13

前言:

單鏈表這個結構,一定要理解鏈的意思,就是找到第一個才能 纔能找到第二個,不像陣列,想知道哪個數據,直接用下標就出來了,鏈表不允許這樣。強制性的必須知道第一個才能 纔能知道第二個,依次類推,這個想法要貫穿鏈表始終。

另外一個就是引入了指針這個概念,還有就是定義結構體的時候,看着程式碼會有點像遞回,我寫完後,試了試,其實就是遞回,可以一直點下去;我上網搜尋了一下,大概意思是有的編譯器會處理這個問題,這個其實不要太在意,就當是指向下一個數據元素的地址就行了,不要鑽牛角尖。

有什麼不對的可以直接說出來,我會修改

程式碼是C語言寫的,可以直接執行,效果就是下面 下麪的效果圖,程式碼可以單獨註釋,然後看單獨的效果,我是直接全部執行了。

程式碼看了一遍懂了,其實不算自己的,只有自己寫出來了,經過自己思考了,纔是自己的,並且寫的過程中也會加深理解概念。

效果圖:

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

#define OK 1
#define ERROR 0

typedef int ElemType;

typedef struct Link			//定義鏈表結點型別 
{
	ElemType data;			//數據域 
	struct Link *next;		//指針域 
}Link,*LinkList;

/*頭插法建立一個單鏈表*/
LinkList HeadInitLink(Link *Lk)
{
	Link *link;
	Lk = (LinkList)malloc(sizeof(Link));	//建立頭結點
	Lk->next=NULL;
	int i = 1;
	while(i<=10)
	{
		link = (LinkList)malloc(sizeof(Link));
		link->data=i;
		link->next=Lk->next;
		Lk->next=link;
		i++;
	}
	return Lk;
} 

/*採用尾插法建立單鏈表*/
LinkList TailInitLink(Link *Lk)
{
	Lk = (LinkList)malloc(sizeof(Link));
	Link *link,*Tail=Lk;
	int i = 1;
	while(i<=10)
	{
		link = (LinkList)malloc(sizeof(Link));
		link->data=i;
		Tail->next=link;			//link是一個地址 
		Tail=link;					//link的地址給了Tail,然後就接着往下了,值並沒改變 
		i++;
	}
	Tail->next=NULL;
	return Lk;
}

/*按序號查詢結點*/
LinkList GetLinkNode(Link *Lk,int i)
{
	Link *p = Lk->next;			//給頭節點的指針,也就是給個地址,開始順着地址查
	if(i==0)
		return Lk;
	if(i<1)
		return NULL;
	int j = 1;
	while(p && j<i)
	{
		p = p->next;
		j++;	
	}
	return p;	
} 

/*按值查詢表結點*/
LinkList ValueElemType(Link *Lk,ElemType e)
{
	Link *p = Lk->next;				//取頭結點指針域,開始查詢
	while(p!=NULL && p->data!=e)	//指針域不爲空,且數據域的值和要找的值不一樣,一樣的話就找到了 
		p=p->next;
	return p;				 
}

/*求鏈表長度*/
int LenghtLink(Link *Lk)
{
	Link *p=Lk->next;
	int lenght = 0;
	while(p)
	{
		p = p->next;
		lenght++;
	}
	return lenght;
}

/*結點插入操作*/
LinkList InsertLink(Link *Lk,int i,ElemType e)
{
	int lenght = LenghtLink(Lk);
	if(i<1||i>lenght)						//判斷插入位置是否合法 
		return NULL;
	Link *pl,*p=Lk;
	pl = (LinkList)malloc(sizeof(Link));	//生成新結點
	int j = 1;
	while(j<i)
	{
		p = p->next;						//在要插入新結點之前;根據指針域地址不斷地找 
		j++;
	}
	pl->data=e;
	pl->next=p->next;
	p->next=pl;
	return Lk; 
}



/*結點刪除操作*/
LinkList DeleteLink(Link *Lk,int i)
{
	int lenght = LenghtLink(Lk);
	if(i<1||i>lenght)				//判斷刪除位置是否合法 
		return NULL;
	Link *dp,*p = Lk;
	int j = 1;
	while(j < i)
	{
		p = p->next;
		j++;
	}
	dp = p->next;					//p->next就是要刪除結點的後繼結點,很重要 
	p->next=dp->next;
	free(dp);						//free(C語言標準函數庫)
	return Lk;
}

int main(void)
{
	Link *Headlink,*Taillink,*Insertlink,*Deletelink,HeadLk,TailLk,InsertLk,DeleteLk;
	Headlink = HeadInitLink(&HeadLk);
	Headlink = Headlink->next;
	printf("頭插法實現單鏈表\n");
	while(Headlink)
	{
		printf("鏈表數據域的值爲:%d 鏈表指針域的值爲:%p\n",Headlink->data,Headlink->next);
		Headlink=Headlink->next;
	}
	printf("\n");
	
	Taillink = TailInitLink(&TailLk);
	//按序號查詢結點值
	printf("按序號查詢結點值\n");
	int address = 6; 
	LinkList p = GetLinkNode(Taillink,address);
	printf("第 %d 個結點數據域的值爲:%d;指針域的值爲:%p\n",address,p->data,p->next);
	printf("\n");
	
	printf("尾插法實現單鏈表\n");
	Taillink = Taillink->next;
	while(Taillink)
	{
		printf("鏈表數據域的值爲:%d 鏈表指針域的值爲:%p\n",Taillink->data,Taillink->next);
		Taillink=Taillink->next;
	}
	printf("\n");
	
	
	//在第6個結點位置插入一個新結點
	printf("在第6個結點位置插入一個新結點\n\n");
	int No = 666;
	Insertlink = TailInitLink(&InsertLk);
	Insertlink = InsertLink(Insertlink,address,No);
	Insertlink = Insertlink->next;
	while(Insertlink)
	{
		printf("新插入結點的鏈表數據域的值爲:%d 指針域的值爲:%p\n",Insertlink->data,Insertlink->next);
		Insertlink=Insertlink->next;
	}
	printf("\n");
	
	//刪除第6個結點
	printf("刪除第6個結點\n\n");
	Deletelink = TailInitLink(&DeleteLk);
	int DeleteBefore = LenghtLink(Deletelink);
	printf("刪除結點前鏈表長度:%d\n",DeleteBefore);
	Deletelink = DeleteLink(Deletelink,address);
	int DeleteAfter = LenghtLink(Deletelink);
	printf("刪除結點後鏈表長度:%d\n",DeleteAfter);
	Deletelink = Deletelink->next;
	while(Deletelink)
	{
		printf("刪除結點後的鏈表數據域的值爲:%d 指針域的值爲:%p\n",Deletelink->data,Deletelink->next);
		Deletelink=Deletelink->next;
	}
	printf("\n");

	return 0;
}