哈喽哈喽大家好啊 今天我要分享的是用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的赋值
内容不多,大家多多交流呦~