C语言提高之——从结构和指针看数据结构链表

本文探讨了如何利用C语言构建单链表数据结构,详细阐述了链表结点的构成,插入数据的步骤,从初始代码到逐步调试优化的过程。总结中强调了在编程中寻找共性、抽象规律的重要性。
摘要由CSDN通过智能技术生成

    通过组合结构和指针可以创建强大的数据结构。该博客只是针对了单链表来看的。

链表说明:

    链表的每一个结点都是一个结构体,其中有两个元素分别是:1、指向下一个结点的指针(link)和该结点数据(value)。其中需要一个根指针指向第一个结点(root)。

插入数据:

  初始代码:

    插入的思想是通过比较当前结构的数据和要插入的数据(new_value)大小,从而判断插入位置。首先需要定义两个指针变量,一个指向当前结构(current),一个指向当前结构的前一个结构(previous)。当判断好位置之后需要做的就是分配一个新结点(new),同时将结点插入。

代码如下:

#include <stdlib.h>
#include <stdio.h>
#include "sll_node.h"

#define FALSE 0
#define TRUE  1

int 
sll_insert( Node *current, int new_value )
{
	Node *previous;
	Node *new;

	/*
	**寻找正确的插入位置,方法是按顺序访问链表,直到到达其值大于或等于
	**新插入的节点值。
	*/
	while( current->value < new_value )
	{
		previous = current;
		current = current->link;
	}

	/*
	**为新节点分配内存,并把新值存储到新结点中,如果内存分配失败,
	**函数返回FALSE。
	*/
	new = (Node *)malloc( sizeof( Node ));
	if( new == NULL )
		return FALSE;
	new->value = new_value;

	/*
	**把新节点插入到链表中,并返回TRUE。
	*/
	new->link = current;
	previous->link = new;
	return TRUE;

}

  调试升级:

    但是其中存在如下问题:1、在判断插入位置的过程中,要判断是否已经访问到最后一个结点,如果不做此判断在循环指针赋值的过程中由于current为空指针会造成间接访问失败。2、如果在链表第一个位置插入结点就需要改变根指针,因此就需要定义个指向根指针的指针(rootp),通过对根指针的指针来对对根节点进行操作。对比上一个代码有如下代码:

#include <stdlib.h>
#include <stdio.h>
#include "sll_node.h"

#define FALSE 0
#define TRUE  1

int 
sll_insert( Node **rootp, int new_value )
{
	Node *current;
	Node *previous;
	Node *new;

	/*
	**得到指向第一个结点的指针。
	*/
	current = *rootp;
	previous = NULL;

	/*
	**寻找正确的插入位置,方法是按顺序访问链表,直到到达其值大于或等于
	**新插入的节点值。
	*/
	while( current != NULL && current->value < new_value )
	{
		previous = current;
		current = current->link;
	}

	/*
	**为新节点分配内存,并把新值存储到新结点中,如果内存分配失败,
	**函数返回FALSE。
	*/
	new = (Node *)malloc( sizeof( Node ));
	if( new == NULL )
		return FALSE;
	new->value = new_value;

	/*
	**把新节点插入到链表中,并返回TRUE。
	*/
	new->link = current;
	if( previous == NULL )
		*rootp = new;
	else
		previous->link = new;
	return TRUE;

}

  优化升级:

    好像调试升级以后就已经很好了,但是其实还可以再进行优化升级,优化升级的思想就是排除起始位置的特殊情况,抓住其中的共性来进行操作。链表的共性就是每一个结点都有一个指向它的指针。第一个结点的指针是根指针(root),其他结点的指针是上一个结点的指针元素(link)。因此在这里定义一个指针(linkp),这个指针可以指向一个字段,该字段是指向下一个结点的指针;最初该指针指向根指针,即指向第一个结点的指针。还需要一个指向当前结点的指针(current)。如此一来我们便将关注中心从结点到了指向下一个结点的指针。对比上边代码如下:

#include <stdlib.h>
#include <stdio.h>
#include "sll_node.h"

#define FALSE 0
#define TRUE  1

int 
sll_insert( register Node **linkp, int new_value )
{
	register Node *current;
	register Node *new;

	/*
	**寻找正确的插入位置,方法是按顺序访问链表,直到到达其值大于或等于
	**新插入的节点值。
	*/
	while((current = *linkp) != NULL && current->value < new_value )
	{
		linkp = ¤t->link;
	}

	/*
	**为新节点分配内存,并把新值存储到新结点中,如果内存分配失败,
	**函数返回FALSE。
	*/
	new = (Node *)malloc( sizeof( Node ));
	if( new == NULL )
		return FALSE;
	new->value = new_value;

	/*
	**把新节点插入到链表中,并返回TRUE。
	*/
	new->link = current;
	*linkp = new;
	return TRUE;

}

总结认识:

    从这三步的优化中第二步是对第一步的错误进行处理的过程,第三步是对第二步的操作优化,优化的思想是从看上去不同的操作中去总结共性,即抽象,找到共性后就可以用一项操作完成多个看似不同的任务,其实我们一直在做这些东西,不仅从知识中找共性,从生活中也可以找共性,从生活的现象中抽象出来的就是规律,其实规律还可以再做进一步的抽象,一步步向上抽象就可以发现一些最根本的规律和真理,然后我们就可以依据这些规律和真理去注重我们日常的一些具体的行为和举动,从而帮助我们处理好一些问题。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值