c語言鏈表的學習

鏈表和數組的不同點在於:數組裏所有的元素的地址都是連着的,不能分散着。而鏈表是可以分散的。但是鏈表和數組也各有各的優點。數組的優點就是佔用的內存小,鏈表的優點是內存可以不是整塊的使用,可以使用一些分散的內存塊,這樣可以有效的利用內存來記錄數據。
比如,綠色的就是用的數組的方式,四個元素只需要四個存儲單元,但是你用鏈表就需要8個存儲單元,但是這8個可以不連續的,但是那兩個還是必須連續的,所以一個結構體內有多個數據的話,內存使用效率就會提高,不過一個結構體內的數據域和指針域還是必須連着的。在數據比較多複雜的時候就可以用鏈表,它可以把各個散落的存儲單元利用起來,提高了利用效率。
在這裏插入圖片描述

靜態鏈表

typedef struct student
{
int score;					
struct student *next;		//創建一個鏈表,包含數據和指針 
} LinkList;
```這是一個結構體,包含一個數據和一個指針

我們可以定義三個靜態鏈表

```cpp
int main()
{
LinkList node1={1,NULL}; 			//創建三個結構體
LinkList node2={2,NULL}; 
LinkList node3={3,NULL}; 
node1.next=&node2;					//第一個結構體內的指針指向第二個結構體地址
node2.next=&node3;
node3.next=NULL;
LinkList *head=&node1;			//創建一個頭結點 
while(head != NULL)				//遍歷鏈表,可以用來查詢鏈表數量 
{
printf("data:%d\n",head->score);
head=head->next;				//這個指針等於指向下一個結構體的指針	
}
}

這樣雖然只有三個數據,但是指針也會佔用存儲單元,相當於一共佔用了6個存儲單元,是數組的兩倍。推薦數據量小就用數組。實際過程中,鏈表一般是動態的,我們需要對數據刪除,增加等等。。。

動態鏈表

其實我覺得動態鏈表和靜態鏈表差不多,就是在增加和刪除節點的時候用靜態鏈表更容易理解,動態鏈表則難一點:
創建結構體,一個數據域一個指針域還是一樣的

	typedef struct student
	{
	int score;					
	struct student *next;		//創建一個鏈表,包含數據和指針 
	} LinkList;

然後我們先循環創建一個鏈表

創建鏈表

	//創建一個列表 
	LinkList *CreateList(int n)  
	{  
	  int i;
	  LinkList *head,*node,*end;					//定義一個頭結點 
	  head=(LinkList*)malloc(sizeof(LinkList));		//給頭結點申請內存 
	  end=head;										//這個爲什麼頭結點等於
	  //尾結點,這是因爲鏈表還沒有創建,所以是沒有數據的,所以頭結點就等於尾結點
	  //我是這麼理解的,剛學 
	  end->next=NULL;								//鏈表最後一個結點的指針爲空 
	  for(i=0;i<n;i++)								//循環創建鏈表 
	  {
		  node=(LinkList*)malloc(sizeof(LinkList));
		  node->score=i;							//給結點數據賦值 
		  end->next=node;							//這個node是新申請的節點
		  //而end是最後一個結點,最後一個結點指向新申請的那個結點,我的理解
		  node->next=NULL;
		  end=node;
	  }
	  return head;
	}

增加結點

這個增加結點的時候,需要定義兩個結構體,其中一個是新申請的節點,另外一個結點是用來交換的,如果沒有這個結點,鏈表會不停的指向結點,相當於循環一樣。
在這裏插入圖片描述
在這裏插入圖片描述
如果只定義一個結構體的話,我的理解是這麼寫的`

	node->next=now;
	now->score=mem;				//賦值於新的節點的數據值 
	now->next=node;				//now的下一個指針指向node

但這樣不行,他會一直在那個結點和增加的節點循環,相當於,所以就需要定義兩個結構體,其中一個用來交換,避免出現這種情況。
在這裏插入圖片描述

//插入在第幾個節點,比如5,插入的節點就是第五個節點 
	int insert(LinkList *head,int num,int mem)
	{
	int i=0;
	LinkList *node=head;
	LinkList *swap;				//用於交換 
	LinkList *now;				//存入的節點
	now=(LinkList*)malloc(sizeof(LinkList));
	while(i<num-1)				//比如back=5,執行四次,此時循環後是第四個node 
		{
		i++;
		node=node->next;
		}
	now->score=mem;				//賦值於新的節點的數據值 
	swap=node->next;			//sw下一個指針指向swap  
	node->next=now;				//node 下一個指針指向now
	now->next=swap;				//now的下一個指針指向swap 
	return 0;	
	}

刪除節點

int dele(LinkList *head,int back)
{
int data,i=0;
LinkList *node=head;
LinkList *now;
while(i<back-1) //比如back=5,執行四次,此時循環後是第四個node
{
i++;
node=node->next;
}
now=node->next; //now等於第五個node的指針 ,這兩個是爲了釋放第五個node的內存
node->next=node->next->next;
free(now);
return 0;
}
刪除指針就比較簡單了,直接講第n個指針指向低n+2個指針,就可以了,然後釋放那個結點的內存就好了
在這裏插入圖片描述

遍歷鏈表

用來打印鏈表內的數據

	void traverlist(LinkList *head)
	{
	LinkList *p=head->next;
	while(NULL!=p)
	{
	printf("該節點數值爲:%d\n",p->score);
	p=p->next;	
	}
	return;	
	}

主函數裏面就調用這些函數就好了

	int main()
	{
	LinkList *phead;
	phead=CreateList(5);
	traverlist(phead);
	printf("111111111111111111111111111\n");
	dele(phead,2);

	traverlist(phead); 
	printf("111111111111111111111111111\n");
	insert(phead,3,111);
	traverlist(phead); 
	}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章