“抽象”《大话数据结构》第三章(链式存储结构)

线性表链式存储结构定义

该链表的每个结点是一个结构体,结构体内部有两个成员,一个成员是整形变量,称作数据域。另一个成员是结构体指针变量,存放下一个节点的首地址。
下面要引出一些概念:
头结点:顾名思义,头结点是整个单链表的最前面的结点,它有点儿特殊,它的数据域不用来存储数据,而是存储链表长度之类的属性信息,然后呢,它的指针域存储则是第一个数据结点的地址。
头指针:就是上面说的,头结点的指针域。

typedef struct Node
{
	ElemType data;
	struct Node *next;
};
typedef struct Node *LinkList;

看到这个代码我是晕的,我居然看不懂。但是,我最终查找资料还是看懂得了!!!

struct Node *next;

这句还算简单,就是定义了一个Node类型的结构体指针;

typedef struct Node *LinkList;

这句就厉害了,它的意思是把struct Node * 取了个别称为LinkList。这样用LinkList定义其它的变量其实就是定义了一个Node类型的结构体指针。原谅我太垃圾了,这也看不懂。

单链表的操作

定义了链表之后,我们也要规定好后续对链表的操作,这样才是抽象数据结构类型嘛。

单链表的读取

要读取第 loca 个数据的算法思路。
1 声明一个结点 p 指向链表的第一个结点,单链表的头结点存着第一个结点的地址,把这个地址给结构体指针,初始化 count从1开始。
2 当 count<loca 时,就遍历链表,让p的指针向后移动,不断指向下一结点,count每次累加1;
3 若到链表末尾p为空,则说明第loca个元素不存在;
4 否则查找成功,返回结点p的数据。

Status SingleListRead(LinkList single_list, int loca, ElemType *read_value)
{
	LinkList p;
	int count = 1;
	p = single_list->next;
	while(p && (count < loca))
	{
		p = p -> next;
		count++;
	}
	if((!p) || (count > loca))
		return ERROR;
	 *read_value = p -> data;
	 return OK;
}

单链表的插入

在loca位置插入数据:
1 声明一结点p指向单链表第一个结点,并且初始化计数器count = 1;
2 当count < loca时,遍历链表,让p的指针后移,不断指向下一个结点,count每次加1.
3 若到链表末尾p为空,则说明第i个元素不存在;
4 否则查找成功,在系统中生成一个空结点s
5 将数据元素e赋值给s->data
6 单链表的插入标准语句:插入结点先存后面结点的地址,再把插入结点的地址给前一结点。
7 返回OK。
这里需要注意,如果是在第loca个位置前插入新的结点,则第一个形参为:

Status SingleListInsert(LinkList *single_list, int loca, ElemType new_data)

如果是在第loca个位置后面插入新的结点,则函数的形参结构为:

Status SingleListInsert(LinkList single_list, int loca, ElemType new_data)

少了个*号。我是这样理解的:
有星号的时候,single_list为指针的指针,使用取地址符+single_list,就是代表遍历是从头结点开始的。
没有星号的时候,遍历是从第一个结点开始的。
本函数选择从第loca个结点的前面插入新的结点,故采用带星号的方式。

Status SingleListInsert(LinkList *single_list, int loca, ElemType new_data)
{
	LinkList p,s;
	int count = 1;
	p = *single_list;
	while(p && count < loca)
	{
		p = p->next;
		count++;
	}
	if(!p || count > loca)
		return ERROR;
	s = (LinkList)malloc(sizeof(Node));
	s->data = new_data;
	s->next = p->next;
	p->next = s;
	return OK
}

单链表的删除

删除单链表第loca个结点算法思路:
1 声明一结点p指向链表第一个结点,初始化count = 1;
2 当count < loca 时,遍历单链表,p不断指向下一个结点,每次count加一;
3 若到链表末尾p为空,则说明该结点不存在,同时也要判断输入的loca是否小于1,是否合法。
4 否则查找成功,将需要删除的结点的地址p->next赋给q,再把q->next赋给p->next.
5 返回删除的值,释放q指针指向地址的空间,声明该空间可用。
6 返回 OK。

Status SingleListDelete(LinkList *single_list, int loca, ElemType *delete_data)
{
	int count = 1;
	LinkList p, q;
	p = *single_list;
	while(p && count < loca)
	{
		p = p->next;
		count++;
	}
	if(!p || count > loca)
		return ERROR;
	q = p ->next;
	*delete_data = q ->data;
	p ->next = q ->next;
	free(q);

	return OK;
}

单链表的创建

单链表整表创建的算法思路:
1 声明一结点p和计数器count;
2 初始化一空链表L;
3 让L的头结点的指针指向NULL,即创建一个带头结点的单链表;
4 循环:
生成一新结点赋值给p
随机生成一数字赋值给p的数据域p->data;
将p插入到头结点与前一新结点之间

  Status SingleListCreate(LinkList *single_list,int n)
{
	LinkList p;
	int count;
	*single_list = (LinkList)malloc(sizeof(SL));

	(*single_list)->data = NULL;
	srand(time(0));
	for(count =0; count < n; count++)
	{
		p = (LinkList)malloc(sizeof(SL));
		p ->data = rand() % 100 + 1;
		p ->next = (*single_list)->next;
		(*single_list)->next = p;

	}
}

单链表的删除

1 声明一结点p和q,q用来下一个存储删除结点的地址。
2 将头结点地址赋给p
3 循环:
将下一个结点地址赋给q保存
释放p的空间
把q的地址给p;

Status SingleListCreate(LinkList *single_list)
{
	LinkList q,p;
	p = (*single_list) ->next;
	while(p)
	{
		q = p->next;
		free(p);
		p = q;
	}
	(*single_list) ->NULL;
	return OK;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值