【复习】手写数据结构之单向链表

思路 : 链表是由一系列结点组成的,每个结点包含一数据域和指针域,指针域指向下一个结点,这样链表就“串”了起来;

相比动态数组 连续空间存储,链表使用随机存储;

单向链表结构如代码注释;

联想到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;
}

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值