【複習】手寫數據結構之單向鏈表

思路 : 鏈表是由一系列結點組成的,每個結點包含一數據域和指針域,指針域指向下一個結點,這樣鏈表就“串”了起來;

相比動態數組 連續空間存儲,鏈表使用隨機存儲;

單向鏈表結構如代碼註釋;

聯想到stl 爲什麼 vector 插入操作比 list 慢很多,vector 每在中間插入一個數 其後邊的數都要移動;

上代碼;主要實現了 鏈表尾部插入;指定位置插入;指定位置刪除 ;指定值第一次出現位置;內存銷燬;

寫代碼的時候老是忘記給新結點在堆上開闢空間  -.- 

/**************************************************************************************
* 單向鏈表實現;
* 19.08.01    by finer.
**************************************************************************************/
#include<stdio.h>
#include<stdlib.h>

//鏈表結點;
typedef struct LINKNODE              // |---------------|
{                                    // |LINKNODE* next;|
	struct LINKNODE* next;           // |_______________|
	void* data;                      // |____*data _____|
}LinkNode;

//鏈表結構;
typedef struct LINKLIST
{
	LinkNode* head;
	int size;
}LinkList;

typedef int(*myPrint)(LinkNode* node);
//列表初始化;
LinkList* init_list(LinkList* list)
{
	list = (LinkList*)malloc(sizeof(LinkList));
	list->head = (LinkNode*)malloc(sizeof(LinkNode));
	list->size = 0;
	list->head->data = NULL;
	list->head->next = NULL;
	return list;
}

//列表尾部插入數據;
void pushBack_list(LinkList* list,void* data )
{
	if (list == NULL)
	{
		return;
	}
	if (data == NULL)
	{
		return;
	}

	LinkNode* finalNode = list->head;
	if (list->head->data == NULL && finalNode->next == NULL) //頭結點;
	{
		finalNode->data = data;
		finalNode->next = NULL;
		list->size++;
	}
	else
	{
	//找尾部指針;
		finalNode = list->head; //定義最後一個node;
		while ( finalNode->next != NULL)
		{
			finalNode = finalNode->next;
		}
		//!!!!!!!!! 爲新的結點開闢內存;
		LinkNode* newNode = (LinkNode*)malloc(sizeof(LinkNode));
		finalNode->next = newNode;

		finalNode->next->data = data;
		finalNode->next->next = NULL;
		list->size++;
	}
}

//指定位置插入數據
void insertPose_list(LinkList* list,void* data, int pos)
{
	if (list == NULL)
		return;
	if (data == NULL)
		return;
	if (pos<0 || pos > list->size)
		return;

	if (pos == 0)
	{
		//爲新結點開內存;
		LinkNode* newNode = (LinkNode*)malloc(sizeof(LinkNode));
		newNode->data = data;

		LinkNode* node = list->head;
		newNode->next = node;
		list->head = newNode;
		list->size++;
	}
	else
	{
		LinkNode* tempNode = list->head; 
		int i = 0;
		while (tempNode->next != NULL && i<pos-1)
		{
			tempNode = tempNode->next;
			i++;
		}

		//tempNode 現在指在 pose 前一個結點;
		LinkNode* node = tempNode->next; //備份結點信息;

		//爲新結點開內存;
		LinkNode* newNode = (LinkNode*)malloc(sizeof(LinkNode));
		newNode->data = data;
		tempNode->next = newNode;
		newNode->next = node;

		list->size++;
	}
	
}

//刪除指定位置元素;
void removeData_list(LinkList* list, int pos)
{
	if (list == NULL)
		return;

	if (pos<0 || pos > list->size)
		return;
	if (pos == 0)
	{
		LinkNode* node = list->head;
		list->head = list->head->next;
		free(node);
		node = NULL;

		list->size--;
	}
	else
	{
		LinkNode* tempNode = list->head;
		int i = 0;
		while (tempNode->next != NULL && i<pos-1)
		{
			tempNode = tempNode->next;
			i++;
		}

		LinkNode* node = tempNode->next;  //備份pos處的結點,用於後續釋放內存;
		tempNode->next = tempNode->next->next; //鏈接pos後的結點;

		//釋放pos處的內存;

		free(node);
		node = NULL;

		list->size--;
	}
}

//查找指定值位置;

int  findPose_list(LinkList* list,void *data)
{
	LinkNode* tempNode = list->head;
	int i = 0;
	while (tempNode->next != NULL  )
	{
		if (*(int*)data == *(int*)tempNode->data)
			break;
		tempNode = tempNode->next;
		//TODO: 提供用戶數據比較接口 這裏直接當int處理;
		i++;
		if (i > list->size)
		{
			printf("沒能找到!");
			return -1;
		}
	}
	return i;
}


void print_list(LinkList* list)
{

	if (list == NULL)
	{	
		return;
	}	
	
	LinkNode* tempNode = list->head; //定義最後一個node;
	while (tempNode != NULL)
	{
		printf( "%d ",*(int*) tempNode->data ); //先轉換爲int指針 在用* 提取地址裏的值;
		tempNode = tempNode->next;
	}
	printf("\n");
	printf("鏈表中共有%d個元素", list->size);
	printf("\n");
}

void  destory_list(LinkList* list)
{

	int size = list->size;
	for (int i = 0; i < size; i++)
	{
		LinkNode* tempNode = list->head;
		while (tempNode->next != NULL)
		{
			tempNode = tempNode->next;
			i++;
		}
		free(tempNode);
		tempNode = NULL;
		list->size--;
	}
}

int main()
{
	LinkList* list = NULL;
	list = init_list(list);

	int a = 3, b = 5,c=10;

	printf("--------測試鏈表尾部輸入--------\n");
	pushBack_list(list, &a);
	pushBack_list(list, &b);
	pushBack_list(list, &c);
	pushBack_list(list, &c);
	pushBack_list(list, &b);
	pushBack_list(list, &b);
	pushBack_list(list, &c);
	pushBack_list(list, &b);
	print_list(list);
	printf("--------測試鏈表指定位置輸入--------\n");
	insertPose_list(list, &c, 0);
	print_list(list);
	printf("--------測試鏈表指定位置刪除數據--------\n");

	removeData_list(list, 0);
	print_list(list);

	printf("--------測試查找指定數值第一次出現位置-------\n");
	print_list(list);
	int idx = findPose_list(list, &c);
	if (idx != -1)
		printf("查找到的位置爲%d \n", idx);


	destory_list(list);
	system("pause");
	return 0;
}

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章