数据结构之单链表

很早之前就想把自己学习数据结构的过程跟大家分享分享,那么现在开始吧。应该是大一开始学的数据结构,到现在也有几个年头了,也当是给自己复习下,总之听到数据结构的名字就给人一种很难学的感觉。
现在想想也没那么可怕,学习的时候把思路整理好,把代码调试通,数据结构不久被你搞定了么!好不扯了,开始正文。


单链表,数据结构的一种。我们用过数组,数组也是用来存储的,单链表这玩意跟它一样一样的。链表分为有头指针和没有头指针的,为了方便我写的是有头指针的!

  • 1 单链表的初始化,先上代码
/**
 * 初始化链表
 *
 * param	ListNode * *	head		双指针
 *
 * return	void
 *
 */

void ListInitiate(ListNode * * head)
{
	* head = (ListNode *)malloc(sizeof(ListNode));
	if (* head == NULL){
		LOG("Hkesd_LOG:内存分配失败!\n");
		exit (1);
	}
	(* head)->next = NULL;
    LOG("Hkesd_LOG:链表初始化成功!\n");
}

初始化一个单链表,就是给链表的头指针分配内存。由于在初始化操作之前,头指针参数head没有具体的地址,在初始化操作时,头指针参数head才得到了具体的地址值,而这个地址值要返回出去,所以这里的头指针参数head设计成指针的指针类型。

  • 2 单链表插入数据
/**
 * 在链表中插入数据
 *
 * param	ListNode *		head		链表头指针
 * param	ElementType		element		待插入的数据
 *
 * return  int				1			插入成功
 *							0			链表为空
 */

int ListInsert(ListNode * head, ElementType element)
{
	if (head == NULL){
		LOG("Hkesd_LOG:链表为空!\n");
		return 0;
	}

	ListNode * tempNode = (ListNode *)malloc(sizeof(ListNode));
	if (tempNode == NULL){
		LOG("Hkesd_LOG:插入元素时分配内存失败\n");
		exit(1);
	}

	tempNode->element = element;
	tempNode->next = head->next;
	head->next = tempNode;

	return 1;
}

在链表中插入数据,这里的方法是头插法,就是一直在链表的头部插入,既然有头插法那么就有尾插法,还有你想往哪插就往哪插的方法,这里就不一一赘述了。

  • 3 删除链表中的数据
/**
 *
 * 删除链表中的数据
 *
 * param	ListNode *		head		链表头指针
 * param	ElementType		element		待删除的数据
 *
 * return	int				1			删除成功
 *							0			链表为空
 */

int ListDelete(ListNode * head, ElementType element)
{
	ListNode * indexNode;
	ListNode * tempNode;

	if (head == NULL){
		LOG("Hkesd_LOG:链表为空!\n");
		return 0;
	}

	indexNode = head;
	while (indexNode->next != NULL && indexNode->next->next != NULL && indexNode ->next-> element != element){
		indexNode = indexNode->next;
	}

	tempNode = indexNode->next;
	indexNode->next = indexNode->next->next;
	free(tempNode);
	return 1;
}

删除元素,无非就是找到元素然后删掉它。在链表中删除元素,有点名堂,因为这是单链表,你没办法知道待删除元素的前置节点在哪,所以就需要我们找到它的前置节点:

while (indexNode->next != NULL && indexNode->next->next != NULL && indexNode ->next-> element != element)
这句话的作用就是找到待删除元素的前置节点,其它的东西看代码就了解了。

  • 4 撤销链表
/**
 *
 * 撤销单链表
 *
 * param	ListNode * *	head		链表头指针地址
 *
 * return	void
 *
 */
void ListDestory(ListNode * * head)
{
	if (* head == NULL){
		LOG("Hkesd_LOG:链表为空!\n");
		return;
	}
	ListNode * firstTmepNode;
	ListNode * secondTempNode;

	firstTmepNode = * head;
	while(firstTmepNode != NULL){
		secondTempNode = firstTmepNode;
		firstTmepNode = firstTmepNode->next;
		free(secondTempNode);
	}

	* head = NULL;
}

因为单链表的节点空间是在程序运行时动态申请的,所以我们要手动回收内存(垃圾回收,这时我就默默的看着Java不说话)

  • 5 最后我写了一个输出链表元素的函数
/**
 *
 * 输出单链表
 *
 * param	ListNode *		head		链表头指针
 *
 * return	void
 *
 */
void PrintList(ListNode * head)
{
	if (head == NULL){
		LOG("Hkesd_LOG:链表为空!\n");
		return;
	}
	
	ListNode * tempNode;
	tempNode = head->next;
    
    printf("当前链表元素为:");
	while(tempNode != NULL){
		printf("%d ", tempNode->element);
        tempNode = tempNode->next;
	}
	printf("\n");
}

链表写到这里,简单的东西也差不多了,写多了不说你们烦我自己都烦,把链表掌握,数据结构就掌握了一半了,后面的栈、队列甚者树都有链表的影子。

点一根烟,扶我起来写代码。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值