思路 : 链表是由一系列结点组成的,每个结点包含一数据域和指针域,指针域指向下一个结点,这样链表就“串”了起来;
相比动态数组 连续空间存储,链表使用随机存储;
单向链表结构如代码注释;
联想到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;
}