思路 : 鏈表是由一系列結點組成的,每個結點包含一數據域和指針域,指針域指向下一個結點,這樣鏈表就“串”了起來;
相比動態數組 連續空間存儲,鏈表使用隨機存儲;
單向鏈表結構如代碼註釋;
聯想到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;
}