顺序表和链表的实现以及优缺点分析

链表:
缺点:以节点为单位存储,不支持随机访问
优点:任意位置插入删除时间复杂度为O(1) ;没有增容问题,插入一个开辟一个空间。
顺序表:
优点:空间连续、支持随机访问
缺点:中间或前面部分的插入删除时间复杂度O(N) ;增容的代价比较大。
下面是我的顺序表以及链表的实现
顺序表:
list.h

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<malloc.h>
#include<assert.h>
//顺序表
typedef int SLDataType;
typedef struct SeqList
{
	SLDataType *arr;//指向动态开辟的数组指针
	size_t size;//有效的数据个数
	size_t capicity;//容量大小
}SeqList,*PSeqList;
//初始化
void SeqListInit(PSeqList psl);
//摧毁
void SeqListDestory(PSeqList psl);
//增容
void CheckCapacity(PSeqList psl);
//尾插
void SeqListPushBack(PSeqList psl, SLDataType x);
//尾删
void SeqListPopBack(PSeqList psl);
//头插
void SeqListPushFront(PSeqList psl, SLDataType x);
//头删
void SeqListPopFront(PSeqList psl);
//查找
int SeqListFind(PSeqList psl, SLDataType x);
//任意位置插入
void SeqListInsert(PSeqList psl, size_t pos, SLDataType x);
//任意位置删除
void SeqListErase(PSeqList psl, size_t pos);
//删除指定数据
void SeqListRemove(PSeqList psl, SLDataType x);
//修改任意位置的数据
void SeqListModify(PSeqList psl, size_t pos, SLDataType x);
//打印
void SeqListPrint(PSeqList psl);

list.c

//顺序表
//初始化
void SeqListInit(PSeqList psl)
{
	assert(psl);
	psl->arr = (SLDataType*)malloc(sizeof(SLDataType) * 10);
	if (psl->arr == NULL)//开辟内存失败
	{
		return;
	}
	psl->capicity = 10;
	psl->size = 0;
}
//增容
void CheckCapacity(PSeqList psl)//检查是否满(增容)
{
	assert(psl);
	if (psl->size == psl->capicity)
	{
	//这里是两种开辟空间的办法
		malloc开辟空间
		//int newcapicity = psl->capicity * 2;//定义新的容量
		//SLDataType *Ptem=(SLDataType *)malloc(sizeof(SLDataType)*newcapicity);//增容
		//if (Ptem == NULL)
		//{
		//	assert(0);
		//	return;
		//}
		//memcpy(Ptem, psl->arr, psl->size * sizeof(SLDataType));//拷贝数据
		//free(psl->arr);
		//psl->arr = Ptem;
		//psl->capicity = newcapicity;
		//realloc开辟空间
		size_t newcapicity = psl->capicity == 0 ? 4 : psl->capicity * 2;
		psl->arr = (SLDataType*)realloc(psl->arr, sizeof(SLDataType)*newcapicity);
	    psl->capicity = newcapicity;
	}

}
//头插
void SeqListPushFront(PSeqList psl, SLDataType x)
{
	assert(psl);
	CheckCapacity(psl);
	int i = 0;
	for (i = psl->size; i > 0; --i)
	{
		psl->arr[i] = psl->arr[i - 1];
	}
	psl->arr[0] = x;
	psl->size++;
}
//头删
void SeqListPopFront(PSeqList psl)
{
	assert(psl);
	if (psl->size == 0)
	{
		printf("顺序表为空\n");
		return;
	}
	int i = 0;
	for (i = 0; i < psl->size ; ++i)
	{
		psl->arr[i] = psl->arr[i + 1];
	}
	--psl->size;
}
//尾插
void SeqListPushBack(PSeqList psl, SLDataType x)
{
	assert(psl);
	CheckCapacity(psl);
	psl->arr[psl->size] =x;
	psl->size++;
}
//尾删
void SeqListPopBack(PSeqList psl)
{
	assert(psl);
	if (psl->arr == 0)//顺序表判空
	{
		printf("顺序表为空\n");
		return;
	}
	psl->size--;
}
//查找
int SeqListFind(PSeqList psl, SLDataType x)
{
	assert(psl);
	int i = 0;
	for (i = 0; i < psl->size; ++i)
	{
		if (psl->arr[i] == x)
			return i;
	}
	printf("没有,找不到\n");
	return -1;
}
//任意位置插入
void SeqListInsert(PSeqList psl, size_t pos, SLDataType x)
{
	assert(psl);
	if (pos<0 || pos>psl->size)
	{
		printf("插入位置不合法\n");
		return;
	}
	CheckCapacity(psl);
	int i = 0;
	for (i = psl->size; i > pos; --i)
	{
		psl->arr[i] = psl->arr[i - 1];
	}
	psl->arr[pos] = x;
	psl->size++;
}
//任意位置删除
void SeqListErase(PSeqList psl, size_t pos)
{
	assert(psl);
	if (pos < 0 || pos > psl->size)
	{
		printf("删除位置非法,删除无效\n");
		return;
	}
	if (psl->size == 0)
	{
		printf("顺序表为空,删除无效\n");
		return;
	}
	int i = 0;
	for (i = pos; i < psl->size - 1; i++)
	{
		psl->arr[i] = psl->arr[i + 1];
	}
	--psl->size;
}
//删除指定数据
void SeqListRemove(PSeqList psl, SLDataType x)
{
	assert(psl);
	int i = 0;
	for (i=0;i<psl->size-1;++i)
	{
		if (psl->arr[i] == x)
		{
			SeqListErase(psl,i);
			return;
		}
	}
	printf("找不到该数据\n");
	return;
}
//修改任意位置的数据
void SeqListModify(PSeqList psl, size_t pos, SLDataType x)
{
	assert(psl);
	if (pos < 0 || pos > psl->size)
	{
		printf("该位置不合法,无法修改\n");
		return;
	}
	int i = 0;
	for (i = 0; i < psl->size ; i++)
	{
		if (i == pos)
		{
			psl->arr[i] = x;
			return;
		}
	}
}
//打印
void SeqListPrint(PSeqList psl)
{
	int i = 0;
	for (i = 0; i < psl->size; ++i)
	{
		printf("%d ", psl->arr[i]);
	}
	printf("\n");
}
//摧毁
void SeqListDestory(PSeqList psl)
{
	assert(psl);
	if (psl->arr)
	{
		free(psl->arr);
		psl->arr = NULL;
		size_t size = 0;
		size_t capicity = 0;
		printf("摧毁成功\n");
	}
}

text.c

//顺序表
int main()
{
	SeqList seq;
	//尾插
	SeqListInit(&seq);
	SeqListPushBack(&seq, 1);
	SeqListPushBack(&seq, 2);
	SeqListPushBack(&seq, 3);
	SeqListPushBack(&seq, 4);
	SeqListPushBack(&seq, 5);
	SeqListPrint(&seq);
	//尾删
	SeqListPopBack(&seq);
	SeqListPrint(&seq);
	SeqListPopBack(&seq);
	SeqListPrint(&seq);
	SeqListPopBack(&seq);
	SeqListPrint(&seq);
	SeqListPopBack(&seq);
	SeqListPrint(&seq);
	SeqListPopBack(&seq);
	SeqListPrint(&seq);
	SeqListPopBack(&seq);
    SeqListPrint(&seq);
	//头插
	SeqListInit(&seq);
	SeqListPushFront(&seq, 1);
	SeqListPushFront(&seq, 2);
	SeqListPushFront(&seq, 3);
	SeqListPushFront(&seq, 4);
	SeqListPushFront(&seq, 5);
	SeqListPrint(&seq);
	//头删
	SeqListPopFront(&seq);
	SeqListPrint(&seq);
	SeqListPopFront(&seq);
	SeqListPrint(&seq);
	SeqListPopFront(&seq);
	SeqListPrint(&seq);
	SeqListPopFront(&seq);
	SeqListPrint(&seq);
	SeqListPopFront(&seq);
	SeqListPrint(&seq);
	//查找
	printf("%d \n", SeqListFind(&seq, 5));
	//指定位置插入
	SeqListInsert(&seq,4,10);
	SeqListPrint(&seq);
	//删除指定 位置 元素
	SeqListErase(&seq,2);
	SeqListPrint(&seq);
	//删除指定数据
	SeqListRemove(&seq,5);
	SeqListPrint(&seq);
	//修改指定位置数据
	SeqListModify(&seq,3,0);
	SeqListPrint(&seq);
	//摧毁全部数据 
	SeqListDestory(&seq);
	system("pause");
	return 0;
}

无头单向不循环链表:
list.h

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<malloc.h>
#include<assert.h>
//无头单链表
typedef int SLTDateType;
typedef struct Node//创建一个结点
{
	SLTDateType data;
	struct Node *next;
}Node,*SList;
void SListInit(SList plist);//初始化
void SListDestory(SList *pplist);//摧毁
struct Node *GetNode(SLTDateType x);//创建结点数据
void SListPushFront(SList *pplist, SLTDateType x);//头插
void SListPopFront(SList *pplist);//头删
void SListPushBack(SList *pplist, SLTDateType x);//尾插
void SListPopBack(SList *pplist);//尾删
Node* SListFind(SList plist, SLTDateType x);//查找数据,返回下标
void SListInsertAfter(Node *pos, SLTDateType x);// 在pos的后面进行插入
void SListEraseAfter(Node *pos);//删除任意位置的结点
void SListPrint(SList plist);//打印

list.c

//无头单向链表
#define _CRT_SECURE_NO_WARNINGS
#include"list.h"
//初始化
void SListInit(SList plist)
{
	assert(plist);
	plist->data = -1;
	plist->next = NULL;
}
//摧毁
void SListDestory(SList *pplist)
{
	Node*cur = *pplist;
	Node* p = NULL;
	if (*pplist == NULL)
	{
		return;
	}
	while (cur!= NULL)
	{
		p = cur;
		cur = cur->next;
		free(p);
	}
	*pplist = NULL;
}
//得到一个结点
struct Node *GetNode(SLTDateType x)
{
	Node *pGet = (Node *)malloc(sizeof(Node));
	assert(pGet);
	pGet->data = x;
	pGet->next = NULL;
	return pGet;
}
//头插
void SListPushFront(SList *pplist, SLTDateType x)
{
	Node *pGet = GetNode(x);
	assert(pplist);
	pGet->next = *pplist;
	*pplist = pGet;
}
//头删
void SListPopFront(SList *pplist)
{
	//空,一个
	if (*pplist == NULL)
	{
		return;
	}
	else if ((*pplist)->next == NULL)
	{
		free(*pplist);
		*pplist = NULL;
		return;
	}
	else
	{
		Node*cur = *pplist;
		*pplist = (*pplist)->next;
		free(cur);
	}
}
//尾插
void SListPushBack(SList *pplist, SLTDateType x)
{
	Node *pGet = GetNode(x);
	if (*pplist == NULL)
	{
		*pplist=pGet;
	}
	else
	{
		Node* tail = *pplist;
		while (tail->next!= NULL)
		{
			tail = tail->next;
		}
		tail->next = pGet;
	}
}
//尾删
void SListPopBack(SList *pplist)
{
	if (*pplist == NULL)
	{
		return;
	}
	else if ((*pplist)->next==NULL)
	{
		free(*pplist);
		*pplist = NULL;
	}
	else
	{
		Node*tail = NULL;
		Node*cur = *pplist;
		while (cur->next != NULL)
		{
			tail = cur;
			cur = cur->next;
		}
		free(cur);
		if (tail != NULL)
			tail->next = NULL;

	}
}
//打印
void SListPrint(SList plist)
{
	Node* cur = plist;
	while (cur != NULL)
	{
		printf("%d->", cur->data);
		cur = cur->next;
	}
	printf("NULL\n");
}
//查找
Node* SListFind(SList plist, SLTDateType x)
{
	Node*cur = plist;
	while (cur!=NULL)
	{
		if (cur->data == x)
			return cur;
		cur = cur->next;
	}
	return NULL;
}
//在pos后插入数据
void SListInsertAfter(Node *pos, SLTDateType x)
{
	Node *pGet = GetNode(x);
	pGet->next=pos->next;
	pos->next = pGet;
}
//删除任意节点的后一个
void SListEraseAfter(Node *pos)
{
	Node* cur = pos->next;
	if (cur != NULL)
	{
		pos->next = pos->next->next;
		free(cur);
	}
	else
		free(pos);
}

text.c

#define _CRT_SECURE_NO_WARNINGS
#include"list.h"
//无头单向链表 
int main()
{
	Node* pList = NULL;
	//头插
	SListPushFront(&pList, 1);
	SListPushFront(&pList, 2);
	SListPushFront(&pList, 3);
	SListPrint(pList);
	//尾插
	SListPushBack(&pList,1);
	SListPushBack(&pList,2);
	SListPushBack(&pList,3);
	SListPushBack(&pList,4);
	SListPrint(pList);
	//头删
	SListPopFront(&pList);
	SListPrint(pList);
	SListPopFront(&pList);
	SListPrint(pList);
	SListPopFront(&pList);
	SListPrint(pList);
	SListPopFront(&pList);
	SListPrint(pList);
	//尾删
	SListPopBack(&pList);
	SListPrint(pList);
	SListPopBack(&pList);
	SListPrint(pList);
	SListPopBack(&pList);
	SListPrint(pList);
	SListPopBack(&pList);
	SListPrint(pList);
	//摧毁
	SListDestory(&pList);
	SListPrint(pList);
	//查找
	printf("%p \n", SListFind(pList,3));
	//修改
	Node*ret = SListFind(pList,2);
	ret->data = 40;
	SListPrint(pList);
	//在pos后插入数据
	SListInsertAfter(ret,50);
	SListPrint(pList);
	//删除结点后面的值
	SListEraseAfter(ret);
	SListPrint(pList);
	system("pause");
	return 0;
}

带头双向循环链表:
list.h

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<malloc.h>
#include<assert.h>
//带头双向循环链表
typedef int LTDataType;
typedef struct ListNode Node;
typedef struct ListNode
{
	struct ListNode* prev;
	LTDataType data;
	struct ListNode* next;
}ListNode;
// 初始化
ListNode* InitList();
//新建一个节点
ListNode* BuyList(LTDataType x);
// 双向链表销毁
void ListDestory(ListNode* plist);
// 双向链表打印
void ListPrint(ListNode* plist);
// 双向链表尾插
void ListPushBack(ListNode* plist, LTDataType x);
// 双向链表尾删
void ListPopBack(ListNode* plist);
// 双向链表头插
void ListPushFront(ListNode* plist, LTDataType x);
// 双向链表头删
void ListPopFront(ListNode* plist);
// 双向链表查找
ListNode* ListFind(ListNode* plist, LTDataType x);
// 双向链表在pos的前面进行插入
void ListInsert(ListNode* pos, LTDataType x);
// 双向链表删除pos位置的节点
void ListErase(ListNode* pos);

list.c

#define _CRT_SECURE_NO_WARNINGS
#include"list.h"
//带头双向循环链表
// 创建返回链表的头结点.
ListNode* InitList()
{
	LTDataType x = 0;
	Node* head = BuyList(x);
	head->prev = head;
	head->next = head;
	return head;
}
//新建一个节点
ListNode* BuyList(LTDataType x)
{
	Node* cur = (Node*)malloc(sizeof(Node));
	cur->data = x;
	cur->prev = NULL;
	cur->next = NULL;
	return cur;
}
// 双向链表销毁
void ListDestory(ListNode* plist)
{
	Node* cur = plist->next;
	Node* next = NULL;
	while (cur != plist)
	{
		next = cur->next;
		free(cur);
		cur = NULL;
		cur=next;
	}
	cur = NULL;

}
// 双向链表头插
void ListPushFront(ListNode* plist, LTDataType x)
{
	Node* cur = plist;
	Node* tail = cur->next;
	Node* newNode = BuyList(x);
	
	cur->next = newNode;
	newNode->prev = cur;

	newNode->next = tail;
	tail->prev = newNode;
}
// 双向链表头删
void ListPopFront(ListNode* plist)
{
	Node* cur = plist->next;
	Node* tail = cur->next;
	plist->next = tail;
	tail->prev = plist;
	free(cur);
	cur = NULL;
}
// 双向链表尾插
void ListPushBack(ListNode* plist, LTDataType x)
{
	Node* cur = plist;
	Node* tail = cur->prev;
	Node* newNode= BuyList(x);

	tail->next = newNode;
	newNode->prev = tail;

	newNode->next = cur;
	cur->prev = newNode;
}
// 双向链表尾删
void ListPopBack(ListNode* plist)
{

	Node* tail = plist->prev;
	Node* p = tail->prev;
	plist->prev = p;
	p->next = plist;
	free(tail);
	tail = NULL;
}
// 双向链表打印
void ListPrint(ListNode* plist)
{
	Node* cur = plist->next;
	while (cur != plist)
	{
		
		printf("%d ", cur->data);
		cur = cur->next;
	}
	printf("\n");
}
// 双向链表查找
ListNode* ListFind(ListNode* plist, LTDataType x)
{
	Node* cur = plist->next;
	while (cur != plist)
	{
		if (cur->data == x)
			return cur;
		cur = cur->next;
	}
	return NULL;
}
// 双向链表在pos的前面进行插入
void ListInsert(ListNode* pos, LTDataType x)
{
	Node* newNode=BuyList(x);
	Node* P = pos->prev;
	P->next = newNode;
	newNode->prev = P;
	newNode->next = pos;
	pos->prev = newNode;
}
// 双向链表删除pos位置的节点
void ListErase(ListNode* pos)
{
	Node* p1 = pos->prev;
	Node* p2 = pos->next;
	p1->next = p2;
	p2->prev = p1;
	free(pos);
	pos = NULL;
}

text.c

#define _CRT_SECURE_NO_WARNINGS
#include"list.h"
//带头双向循环链表
int main()
{
	Node* List = InitList();
	//尾插
	ListPushBack(List,1);
	ListPushBack(List,2);
	ListPushBack(List,3);
	ListPushBack(List,4);
	ListPushBack(List,5);
	ListPushBack(List,6);
	ListPrint(List);
	//尾删
	ListPopBack(List);
	ListPrint(List);
	ListPopBack(List);
	ListPrint(List);
	ListPopBack(List);
	ListPrint(List);
	ListPopBack(List);
	ListPrint(List);
	ListPopBack(List);
	ListPrint(List);
	ListPopBack(List);
	ListPrint(List);
	//头插
	ListPushFront(List,1);
	ListPushFront(List,2);
	ListPushFront(List,3);
	ListPushFront(List,4);
	ListPushFront(List,5);
	ListPushFront(List,6);
	ListPrint(List);
	//头删
	ListPopFront(List);
	ListPrint(List);
	ListPopFront(List);
	ListPrint(List);
	ListPopFront(List);
	ListPrint(List);
	ListPopFront(List);
	ListPrint(List);
	ListPopFront(List);
	ListPrint(List);
	ListPopFront(List);
	ListPrint(List);
	摧毁
	//ListDestory(List);
	//查找
	printf("%p \n",ListFind(List, 5));
	//pos前插入
	ListInsert(ListFind(List, 2), 40);
	ListPrint(List);
	//删除pos节点
	ListErase(ListFind(List, 40));
	ListPrint(List);
	system("pause");
	return 0;
}

个人觉得其实理解逻辑之后,代码就很好写了。所以还是重理解逻辑。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值