数据结构从零单排2——链表(1)

大家好久不见(搞得这种辣鸡文章有人看一样。。。)

最近在忙学校里的项目和学车,再加上懒,好久没有更新这个系列了,emmmm,今天终于有点时间更新一下了,今天介绍数据结构中线性表的另一个知识点——链表。


链表的定义

线性表的链式存储特点是用任意的存储单元存储线性表的数据元素,其存储单元可以是连续,也可以是不连续的(顺序表一定是连续的),为了表示链表前后元素的关系,在元素中在其本身携带的数据基础上,添加一个指向后面一个节点的存储映像(也就是下一个节点的地址)。链表的一个节点中,存储数据的部分称为数据域,存储地址的部分称为指针域。
如图所示即链表的直观表示:


链表的存储结构

typedef struct LNode {
	int data;
	struct LNode *next;
}LNode, *LinkList;

其中data部分即数据域,他的类型可以是各种各样的,这里只是用int作为例子,next即为下一节点的地址。

链表的实现(增、删、顺序合并)

直接上代码:
stdafx.h
#include <stdio.h>
#include <stdlib.h>


typedef struct LNode {
	int data;
	struct LNode *next;
}LNode, *LinkList;

/************************************************************************/
/*创建链表                                                              */
/************************************************************************/
LinkList initLinkedList(); 

/************************************************************************/
/*从链表中插入值                                                        */
/*L:想要插入值的链表													*/
/*i:想要插入的位置														*/
/*data:想要插入的值												*/
/************************************************************************/
int insertElement(LinkList L, int i, int data); 

/************************************************************************/
/*从链表中插入值                                                        */
/*L:想要插入值的链表													*/
/*i:想要插入的位置														*/
/*return: 0:删除失败 1:删除成功*/
/************************************************************************/
int deleteElement(LinkList L, int i);

/************************************************************************/
/* 合并两个有序列表                                                     */
/************************************************************************/
LinkList mergeList(LinkList La, LinkList Lb);


// LinkedListTest.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"

LinkList testInsert();
void testDelete();
void testMergeList();

int main(void)
{
	//都是测试函数
	testInsert();
	testDelete();
	testMergeList();
	system("pause");
	return 0;
}

//初始化函数
LinkList initLinkedList() {
	LinkList L;
	L = (LinkList)malloc(sizeof(LNode));
	if (L)
	{
		L->next = NULL;
		return L;
	} else {
		return 0;
	}
}

//插入
int insertElement(LinkList L, int i, int data) {
	int j = 0;
	LinkList p = L;
	LinkList node = initLinkedList();
	if (node) {
		node->data = data;
	} else {
		return 0;
	}
	while(p && j < i) {
		p = p->next;
		j++;
	}
	if (!p || j > i) {
		return 0;
	}
	node->next = p->next;
	p->next = node;
	return 1;
}

//删除
int deleteElement(LinkList L, int i) {
	int j = 0;
	LinkList p = L;
	LinkList q = L->next;
	while(q && j < i) {
		q = q->next;
		p = p->next;
		j++;
	}
	if (!q || j > i) {
		return 0;
	}
	p->next = q->next;
	free(q);
	return 1;
}

//合并
LinkList mergeList(LinkList La, LinkList Lb) {
	LinkList pa = La->next;
	LinkList pb = Lb->next;
	LinkList Lc, pc;
	Lc = pc = La; //把A链表的头结点作为C链表的头结点

	while(pa && pb) {
		if (pa->data <= pb->data) { 
			pc->next = pa;
			pc = pa;
			pa = pa->next;
		} else {
			pc->next = pb;
			pc = pb;
			pb = pb->next;
		}
	}
	//插入剩余节点
	pc->next = pa ? pa : pb;
	//释放资源
	free(Lb); //这里只要释放B链表的头就可以了
	return Lc;
}

LinkList testInsert() {
	int i = 0;
	LinkList LHead = initLinkedList();
	for (i = 0;i < 5;i++) 
	{
		if (!insertElement(LHead, 0, i))
		{
			printf("插入第%d元素时失败",i);
			break;
		}
	}
	LinkList p = LHead->next;
	if (i >= 5)
	{
		while(p) {
			printf("%d\t", p->data);
			p = p->next;
		}
		printf("\n");
	}
	return LHead;
}

void testDelete() {
	LinkList LHead = testInsert();
	
	deleteElement(LHead, 2);
	LinkList p = LHead->next;
	while(p) {
		printf("%d\t", p->data);
		p = p->next;
	}
}

void testMergeList() {
	LinkList La = initLinkedList();
	LinkList Lb = initLinkedList();
	insertElement(La, 0, 9);
	insertElement(La, 0, 6);
	insertElement(La, 0, 3);
	insertElement(Lb, 0, 8);
	insertElement(Lb, 0, 7);
	insertElement(Lb, 0, 1);
	LinkList Lc = mergeList(La, Lb);
	LinkList pc = Lc->next;
	while(pc) {
		printf("%d\t", pc->data);
		pc = pc->next;
	}
	printf("\n");
}

这几个功能比较简单,实现起来并不难,其中test开头函数都是测试增删以及合并功能的函数,偷懒就写的比较随意,看看就好了。
运行结果:

这里因为测试delete的时候顺便把insert也给测了,所以就运行了俩test函数

小结

可以看出,链表和顺序表虽然同为线性表,但是他们的区别以及特长都是不一样的,顺序表的存储结构是相邻的,访问数据方便但是插入删除非常耗时,而链表恰恰相反,他的删除和插入都很方便,但是遍历访问比较耗时,所以在实际运用中,具体选择哪种数据结构是根据具体情况来判断的,这一节就先到这里,下一节会介绍循环链表,双向链表以及一元二次多项式的问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值