单链表的创建,查找(按值查找),销毁,打印

       单链表是数据结构中较为“简单”的一部分,但是它却是很重要的一部分。二叉树,线索二叉树,哈希函数等等的相关操作都离不开链表,因此搞懂单链表显得尤为重要。下面是我对链表简单操作的一些理解。(本文中所有链表代码均无头结点,ppFirst指的是首元结点)

        首先,单链表的本质得先清楚。单链表是一种链式存储的线性表。它可以解决数组无法存储多种类型的问题。我们通过图简单的认识一下链表:

        其次,单链表的相关操作需要掌握。(重中之重)

1 单链表成员的创建,即结点的创建。

        链表结点的创建,首先声明结构体,结构体中包括数据域和指针域:代码如下所示:

typedef int DataType; 
//创建单链表的成员,其实就是结点
typedef struct SListNode { 
 DataType data; // 值
struct SListNode *pNext; // 指向下一个结点
} SListNode; //SListNode为这个结构体的别名

2 初始化单链表

        初始化单链表也就是将首元结点初始化为空,代码如下:

void SListInit(SListNode **ppFirst)
{
	*ppFirst = NULL;
}

3 打印单链表

        打印单链表,首先判断链表是否为空,为空则直接打印“空链表”,否则循环打印出每个结点的数据

//打印
void SListprint(SListNode *ppFirst)
{//判断是否为空链表
    SListNode *p = ppFirst;
	if(p == NULL)
	{
		printf("空链表\n");
	}
	else{
//非空链表:循环打印每个链表的data,循环结束条件为遇到空指针
		for(p = ppFirst;p != NULL;p = p->pNext)
		{
			printf("%d  ",p->data);
		}
		printf("NULL\n");
	}
}

4 创建新结点

创建新的结点,新结点包含数据域和指针域。将其封装为函数,调用更加方便。主要代码如下:

//创建新结点,结点的数据域为data,pNext域设置为空
SListNode *_CreateNode(DataType data)
{ 
    SListNode *NewNode; //声明新结点
	NewNode = (SListNode *)malloc(sizeof(SListNode));//创建新结点
	if(NewNode == NULL)
	{
		return;
	}//创建失败
	NewNode ->data = data;
	NewNode ->pNext = NULL;//创建成功
	
}

5  单链表的查找

        按值查找,找到后返回第一个的结点指针,如果没找到,返回NULL

// 按值查找,返回第一个找到的结点指针,如果没找到,返回NULL
SListNode * SListFind(SListNode *ppFirst, DataType data)
{	
	SListNode *cur;
	//顺序查找,去遍历
	for(cur = ppFirst; cur != NULL; cur = cur->pNext)
	{
		if( cur->data == data)
		{
			return cur;
		}
	}
	return NULL;

}

6 销毁单链表

销毁单链表也就是将每个结点free掉,并且将首元结点置空。

// 销毁 (记录并删除链表中的每个结点,并将头结点置为空)
void SListDestroy(SListNode **ppFirst)
{
	SListNode *pre;
	SListNode *cur;
	assert(*ppFirst);
    pre = *ppFirst;
	for(pre = *ppFirst; pre != NULL;pre = cur)
	{
		cur = pre ->pNext;
		free(pre);
	}
    *ppFirst = NULL;
}

7 单链表的尾插

此处未做详细说明,链表的插入以及删除在下一篇博客中详细说明。

// 尾部插入(先找到最后一个结点,并把它记录下来,再把最后一个结点的pNext域指向新的结点)
void SListPushBack(SListNode** ppFirst, DataType data)
{
	SListNode *p;//新结点p
	SListNode *p1; 
	p = _CreateNode(data); 
	p1 = *ppFirst;//用来遍历链表(开始位于头结点处)
	//空链表
	if( (*ppFirst) == NULL ){
		*ppFirst = p;
		return;
	} else{
		for(p1 = *ppFirst;p1->pNext != NULL;p1 = p1->pNext)
	       {

        	}
	  p1 ->pNext = p;//此时p1为最后一个结点
	}

}

        上述链表操作的测试代码如下:

#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <windows.h>

int main()
{
    SListNode *result;
    SListNode *p1;
    SListInit(&p1);
    SListPushBack(&p1,1);
    SListPushBack(&p1,2);
    SListPushBack(&p1,3);
    SListPushBack(&p1,2);
    SListPushBack(&p1,5);
    SListPushBack(&p1,2);
    SListPushBack(&p1,6);


    
    result = SListFind(p1,5);
    SListprint(result);
    SListDestroy(&p1);
    SListprint(p1);

    system("pause");
	return 0;
}

        上述仅仅是单链表的简单操作,重要的插入与删除将在下一篇博客中详细说明。

猜你喜欢

转载自blog.csdn.net/zr147258369/article/details/82960945