顺序表和链表

本文介绍了如何使用C语言实现顺序表和链表的数据结构,包括初始化、尾插、尾删等基本操作。顺序表通过动态扩容处理插入,链表则通过创建新节点进行头插和尾插。文章强调了理解数据结构特性、内存管理和指针操作的重要性。
摘要由CSDN通过智能技术生成

哈喽哈喽大家好啊 今天我要分享的是用C语言实现顺序表和链表。

顺序表和链表是很重要的两种结构,它们各有优缺.

我们来简单比较一下:

一、顺序表

#include<stdio.h>
#include <stdlib.h>
#include <assert.h>
typedef int SLDatatype;
typedef struct seqList
{
	SLDatatype *a ;
	int size;//记录SLDatatype个数
	int capacity;//扩充容量
}SL;

void SLinit(SL* ps);//初始化

void SLPushBack(SL* ps, SLDatatype x);//尾插

void SLPopBack(SL* ps);//尾删

void SLdestory(SL* ps);//释放数组,size capacity赋0

void SLprint(SL* ps);//打印

插入和删除方面,我只给出尾插尾删的操作.

#include "seqList.h"
void SLinit(SL* ps)//初始化
{
	assert(ps);

	ps->a=NULL;
	ps->size = 0;
	ps->capacity = 0;
}
void SLPushBack(SL* ps, SLDatatype x)//尾插
{
	assert(ps);
	if (ps->capacity == ps->size)
	{
		int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
		SLDatatype *tmp= (SLDatatype*)realloc(ps->a, newcapacity * sizeof(SLDatatype));
		if (tmp == 0)//realloc开辟失败
		{
			perror("realloc fail");
			exit(-1);//退出
		}
		ps->a = tmp;
		ps->capacity = newcapacity;
	}
	ps->a[ps->size] = x;
	ps->size++;
}
void SLPopBack(SL* ps)//尾删
{
	assert(ps);
	assert(ps->size > 0);
	ps->size--;
}
void SLdestory(SL* ps)//释放数组,size capacity赋0
{
	assert(ps);
		if (ps->a !=NULL)
		{
			free(ps->a);
			ps->size = ps->capacity = 0;
		}
}
void SLprint(SL* ps)//打印
{
	assert(ps);
	int i = 0;
	for (i = 0; i < ps->size; i++)
	{
		printf("%d ", ps->a[i]);
	}
	printf("\n");
}

在编写过程中需要注意的几点如下:

①定义结构体的时候搞清楚size和capacity的含义

②考虑插入过程中的容量扩充

③考虑尾删为什么不free

④malloc记得free避免内存泄漏

二、链表

下面给出的操作,均为单链表.

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
typedef int SLTDateType;
typedef struct SListNode
{
	SLTDateType data;
	struct SListNode* next;
}SListNode;

// 动态申请一个节点
SListNode* BuySListNode(SLTDateType x);

// 单链表打印
void SListPrint(SListNode* plist);

// 单链表头插
void SListPushFront(SListNode** pplist, SLTDateType x);

// 单链表的尾插
void SListPushBack(SListNode** pplist, SLTDateType x);

// 单链表的尾删
void SListPopBack(SListNode** pplist);

// 单链表头删
void SListPopFront(SListNode** pplist);

// 单链表查找
SListNode* SListFind(SListNode* plist, SLTDateType x);

// 单链表在pos位置之后插入x
// 分析思考为什么不在pos位置之前插入?
void SListInsertAfter(SListNode* pos, SLTDateType x);
// 单链表删除pos位置之后的值
// 分析思考为什么不删除pos位置?
void SListEraseAfter(SListNode* pos);

//单链表的创建
SListNode* SListcreate(int n);

// 单链表的销毁
void SListDestroy(SListNode**plist);

插入和删除方面,给出头插头删和尾插尾删的操作.

#define _CRT_SECURE_NO_WARNINGS 1
#include"SList.h"

SListNode* SListcreate(int n)//单链表的创建
{
	SListNode* phead, * ptail;
	phead = ptail = NULL;
	int i = 0;
	for (i = 0; i < n; i++)
	{
		SListNode* new = BuySListNode(i);
		if (phead  == NULL)
		{
			phead =ptail= new;
		}
		else
		{
			ptail->next = new;
			ptail = new;
		}
	}
	return phead;
}

// 单链表的销毁
void SListDestroy(SListNode** plist)
{
	SListNode* cur = *plist;
	while (cur)
	{
		SListNode* next = cur->next;
		free(cur);
		cur = next;
	}
	*plist = NULL;
}

SListNode* BuySListNode(SLTDateType x)//创建新结点
{
	SListNode* newnode = (SListNode*)malloc(sizeof(SListNode));
	if (newnode == NULL)
	{
		perror("malloc fail");
		exit(-1);
	}
	newnode->data = x;
	newnode->next = NULL;
	return newnode;
}

void SListPrint(SListNode* plist)//打印链表
{
	SListNode* cur = plist;

    while(cur)
	{
		printf("%d->",cur->data);
		cur = cur->next;
	}
	printf("NULL\n");
}

void SListPushBack(SListNode** pplist, SLTDateType x)//尾插
{
	SListNode* plist = BuySListNode(x);
		if (*pplist == NULL)
		{
			*pplist = plist;
		}
		else
		{
			SListNode* cur = *pplist;
			while (cur->next)
			{
				cur = cur->next;
			}
			cur->next = plist;
		}
}


void SListPopBack(SListNode** pplist)//尾删
{
	assert(*pplist);
	if ((*pplist)->next == NULL)
	{
		free(*pplist);
		*pplist = NULL;
	}
	else
	{
		SListNode* tail = *pplist;
		while(tail->next->next)
		{
			tail = tail->next;
		}
		free(tail->next);
		tail->next = NULL;
	}
}

void SListPushFront(SListNode** pplist, SLTDateType x)//头插
{
	SListNode* newnode = BuySListNode(x);
	newnode->next = *pplist;
	*pplist = newnode;
}


void SListPopFront(SListNode** pplist)//头删
{
	assert(*pplist);
	if ((*pplist)->next == NULL)
	{
		free(*pplist);
		*pplist = NULL;
	}
	else
	{
		SListNode* head = *pplist;
		*pplist = (*pplist)->next;
		free(head);
	}
}

SListNode* SListFind(SListNode* plist, SLTDateType x)//寻找链表中的值
{
	SListNode* cur = plist;
	while (cur)
	{
		if (cur->data == x)
		{
			return cur;
		}
		cur = cur->next;
	}
	return NULL;
}

void SListInsertAfter(SListNode* pos, SLTDateType x)//插入pos后
{
	assert(pos);
	SListNode* newnode = BuySListNode(x);
	newnode->next = pos->next;
	pos->next=newnode;
}


void SListEraseAfter(SListNode* pos)//删除pos后
{
	assert(pos);
	SListNode* cur = pos->next;
	if (cur == NULL)
	{
		return;
	}
	else
	{
		pos->next = cur->next;
		free(cur);
	}
	

}

需要注意的几点:

①搞清楚头和尾的概念

②我在插入删除过程中用到了二级指针(一级指针也可以,多尝试下

③要注意next的赋值

内容不多,大家多多交流呦~

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值