C++语言:单链表的增删查改,数据结构

链表中的数据是以结点来表示的,每个结点的构成:元素( 数据元素的映象) +  指针(指示后继元素存储位置),元素就是存储数据的存储单元,指针就是连接每个结点的地址数据。
以“结点的序列”表示线性表称作 线性链表(单链表)
单链表是链式存取的结构,为找第 i 个数据元素,必须先找到第 i-1 个数据元素。
因此,查找第 i 个数据元素的基本操作为:移动指针,比较 j 和 i
单链表
1、链接存储方法
链接方式存储的线性表简称为链表(Linked List)。
链表的具体存储表示为:
① 用一组任意的 存储单元来存放线性表的结点(这组存储单元既可以是连续的,也可以是不连续的)
② 链表中结点的逻辑次序和物理次序不一定相同。为了能正确表示结点间的逻辑关系,在存储每个结点值的同时,还必须存储指示其后继结点的地址(或位置)信息(称为 指针(pointer)或链(link))
注意:
链式存储是最常用的存储方式之一,它不仅可用来表示线性表,而且可用来表示各种非线性的数据结构。
2、链表的结点结构
┌───┬───┐
│data │next │
└───┴───┘
data域--存放结点值的数据域
next域--存放结点的直接后继的地址(位置)的 指针域(链域)
注意:
①链表通过每个结点的链域将线性表的n个结点按其逻辑顺序链接在一起的。
②每个结点只有一个链域的链表称为单链表(Single Linked List)。
3、头指针head和终端结点指针域的表示
单链表中每个结点的存储地址是存放在其前趋结点next域中,而开始结点无前趋,故应设头指针head指向开始结点。
注意:
链表由头 指针唯一确定,单链表可以用头指针的名字来命名。
终端结点无后继,故终端结点的指针域为空,即NULL。
4、单链表的一般图示法
由于我们常常只注重结点间的逻辑顺序,不关心每个结点的实际位置,可以用箭头来表示链域中的指针,线性表(bat,cat,fat,hat, jat,lat,mat)的单链表就可以表示为下图形式。
5、单链表类型描述
typedef char DataType; //假设结点的数据域类型为字符
typedef struct node{ //结点类型定义
DataType data; //结点的数据域
struct node *next;//结点的 指针
}ListNode;
typedef ListNode *LinkList;
ListNode *p;
LinkList head;
注意:
①LinkList和ListNode是不同名字的同一个指针类型(命名的不同是为了概念上更明确)
②*LinkList类型的 指针变量head表示它是单链表的头指针
③ListNode类型的指针变量p表示它是指向某一结点的指针
SListNode.h
#ifndef __SLISTNODE_H__
#define __SLISTNODE_H__

#define _CRT_SECURE_NO_WARNINGS 1  

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

typedef int DataType;

typedef struct SListNode
{
	DataType data;
	struct SListNode* next;
}SListNode;

SListNode* BuyNode(DataType x);//申请节点  
void PrintSlist(SListNode* pHead);//打印链表  
void InitSList(SListNode*& pHead);//初始化链表  
void PushBack(SListNode*& pHead, DataType x);//尾插  
void PopBack(SListNode*& pHead);//尾删  
void PushFront(SListNode*& pHead, DataType x);//前插  
void PopFront(SListNode*& pHead);//头删  
void Insert(SListNode*& pHead, SListNode*& pos, DataType x);//在pos前插入一个数据  
void Erase(SListNode*& pHead, SListNode* pos);//删除指定位置  
void Remove(SListNode*& pHead, DataType x);//删除x  
SListNode* Find(SListNode*& pHead, DataType x);//寻找x  
void DestoryList(SListNode*& pHead);//销毁  

#endif;//__SEQLIST_H__
SListNode.c
#include"SListNode.h"

SListNode* BuyNode(DataType x)//申请节点  
{
	SListNode *node = (SListNode*)malloc(sizeof(SListNode));
	node->data = x;
	node->next = NULL;
	return node;
}

void PrintSlist(SListNode* pHead)//打印链表  
{
	SListNode *cur = pHead;//链表最后一项为NULL=0
	while (cur)
	{
		printf("%d ", cur->data);
		cur = cur->next;
	}
	printf("\n");
}

void InitSList(SListNode*& pHead)//初始化链表  
{
	assert(pHead);
	pHead = NULL;
}

void PushBack(SListNode*& pHead, DataType x)//尾插  
{
	assert(pHead);
	if (pHead == NULL)
	{
		pHead = BuyNode(x);
	}
	else
	{
		SListNode* cur = pHead;
		while (cur->next)
		{
			cur = cur->next;
		}
		cur->next = BuyNode(x);
	}
}

void PopBack(SListNode*& pHead)//尾删  
{
	assert(pHead);
	//没有节点  
	if (pHead == NULL)
	{
		printf("The List is empty\n");
		return;
	}
	//一个节点  
	else if (pHead->next == NULL)
	{
		free(pHead);
		pHead = NULL;
	}
	//多个节点  
	else
	{
		SListNode *prev = NULL;
		SListNode *cur = NULL;
		cur = pHead;
		while (cur->next)
		{
			prev = cur;
			cur = cur->next;
		}
		free(cur);
		prev->next = NULL;
	}
}

void PushFront(SListNode*& pHead, DataType x)//前插  
{ 
	assert(pHead);
	if (pHead == NULL)
	{
		pHead = BuyNode(x);
	}
	else
	{
		SListNode* tmp = BuyNode(x);
		tmp->next = pHead;
		pHead = tmp;
	}
}

void PopFront(SListNode*& pHead)//头删  
{
	assert(pHead);
	//没有节点  
	if (pHead == NULL)
	{
		printf("The List is empty\n");
		return;
	}
	//other
	else if (pHead->next == NULL)//判断是否只有一个节点  
	{
		free(pHead);
		pHead = NULL;
	}
	else//多个节点,next接收pHead的值,防止释放后找不到后面的链表
	{
		SListNode* next = pHead->next;
		free(pHead);
		pHead = next;
	}
}

void Insert(SListNode*& pHead, SListNode*& pos, DataType x)//在pos前插入一个数据  
{
	assert(pos);
	assert(pHead);
	if (pos == pHead)
	{
		PushFront(pHead, x);
	}
	else
	{
		SListNode* prev = NULL, *cur = NULL;
		cur = pHead;
		while (cur != pos)
		{
			prev = cur;
			cur = cur->next;
		}
		SListNode* tmp = BuyNode(x);
		tmp->next = cur;
		prev->next = tmp;
	}
}

void Erase(SListNode*& pHead, SListNode* pos)//删除指定位置  
{
	assert(pos);
	assert(pHead);
	if (pos == pHead)
	{
		PopFront(pHead);
	}
	else if (pHead->next == NULL)
	{
		SListNode* prev = NULL, *cur = NULL;
		cur = pHead;
		while (cur->next)
		{
			prev = cur;
			cur = cur->next;
		}
		free(cur);
		prev->next = NULL;
	}
	else
	{
		SListNode* prev = NULL, *cur = NULL;
		cur = pHead;
		while (cur != pos)
		{
			prev = cur;
			cur = cur->next;
		}
		prev->next = cur->next;
		free(cur);
	}
}

void Remove(SListNode*& pHead, DataType x)//删除x  
{
	if (pHead == NULL)//判断是否为空链表  
	{
		printf("The List is empty\n");
		return;
	}
	else if (pHead->data == x)
	{
		SListNode* next = pHead->next;
		free(pHead);
		pHead = next;
	}
	else
	{
		SListNode* prev = NULL, *cur = NULL;
		cur = pHead;
		while (cur->data != x)
		{
			prev = cur;
			cur = cur->next;
		}
		prev->next = cur->next;
		free(cur);
	}
}

SListNode* Find(SListNode*& pHead, DataType x)//寻找x  
{
	SListNode* cur = pHead;
	while (cur)
	{
		if (cur->data == x)
		{
			return cur;
		}
		cur = cur->next;
	}
	return NULL;
}

void DestoryList(SListNode*& pHead)//销毁  
{
	SListNode* cur = pHead;
	while (cur)
	{
		SListNode* tmp = cur;
		cur = cur->next;
		free(tmp);
		tmp = NULL;
	}
}



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值