顺序表和基于顺序表的栈和队列的实现(c思想实现)

数据结构主要分为线性结构和非线性结构

 


目录

关于void*和NULL

顺序表

头文件(具体功能划分)

dm_02_seqlist.cpp(实现每一个顺序表的基本操作)

测试程序 main()

测试结果:

基于顺序表的栈:

栈的头文件:

栈的实现文件:

栈的测试文件:

栈的测试结果:

基于顺序表的队列:

队列的头文件:

队列的实现文件:

队列的测试文件:

队列的测试结果:


关于void*和NULL

 

NULL  #define NULL   ((void *)0) 

空指针有指向,但是它指向的地址是特殊的(0),在内存分配方面,较小的地址是不用来存放数据的,也不允许程序访问的,所以空指针不能操作该地址里的东西,我们就理解为“指针指向了空,无法操作了”。

void * 类型指针

这个类型指针指向了实实在在的存放数据的地址,但是该地址存放的数据的数据类型我们暂时不知道。所以先弄成void* 类型,后期一般要强制转换的(如指针++ -- 等操作,void*没有类型,步长不知道,必须强转,如(char*))。

顺序表

头文件(具体功能划分)

 dm_02_seqlist.h

#pragma once
#include"iostream"

using namespace std;

typedef void Seqlist;
typedef void SeqlistNode;

Seqlist* SeqlistCreat(int capacity);//创建固定大小的线性表
void SeqlistDestory(Seqlist*list);//销毁线性表
void SeqlistClear(Seqlist*list);//清空
int SeqlistLength(Seqlist*list);//返回长度
int SeqlistCapacity(Seqlist*list);//返回容量
int SeqlistInsert(Seqlist*list, SeqlistNode*node,int pos);//指定位置插入节点
SeqlistNode* SeqlistGet(Seqlist*list, int pos);//获取指定位置节点
SeqlistNode*SeqlistDelete(Seqlist*list, int pos);//删除指定位置节点


dm_02_seqlist.cpp(实现每一个顺序表的基本操作)

#include"dm_02_seqlist.h"

struct TSeqlist
{
	int len;//定义数组长度
	int capacity;
	unsigned int **node;//定义数组的首地址,二级指针 动态分配内存空间 或指针数组 每个元素均是一个指针 int *node[n];
	                    //二级内存结构
};

//底层业务节点只是操作上层传入的指针,节点的内存由上层业务分配
//由于未知上层业务节点类型,故定义unsigneg int**指针类型,可以指向任何业务节点

Seqlist* SeqlistCreat(int capacity)
{
	TSeqlist *tmp;
	int ret = 0;
	tmp = (TSeqlist*)malloc(sizeof(TSeqlist));//创建顺序表句柄
	if (tmp == NULL)
	{
		ret = -1;
		cout << "func SeqlistCreat malloc err" << ret << endl;
		return NULL;
	}
	memset(tmp, 0, sizeof(TSeqlist));//初始化内存空间0

	tmp->node = (unsigned int **)malloc(sizeof(unsigned int *)*capacity);
	if (tmp->node == NULL)
	{
		ret = -2;
		cout << "func SeqlistCreat malloc err" << ret << endl;
		return NULL;
	}
	tmp->capacity = capacity;
	tmp->len = 0;
	return tmp;//Seqlist* 为void*型 
}
//释放内存销毁链表
void SeqlistDestory(Seqlist*list)
{
	TSeqlist*tlist = NULL;//自己知道数据类型
	if (list == NULL)
	{
		cout << "传入为空指针" << endl;
		return;
	}
	tlist = (TSeqlist*)list;
	if (tlist->node != NULL)
	{
		free(tlist->node);
	}
	free(tlist);
}
//清空链表
void SeqlistClear(Seqlist*list)
{
	TSeqlist*tlist = NULL;//自己知道数据类型
	if (list == NULL)
	{
		cout << "传入为空指针" << endl;
		return;
	}
	tlist->len = 0;//清空链表即回到初始化状态,len=0

}
//返回链表长度
int SeqlistLength(Seqlist*list)
{
	if (list == NULL)
	{
		cout << "传入为空指针" << endl;
		return -1;
	}
	TSeqlist*tlist = (TSeqlist*)list;
	return tlist->len;
}

int SeqlistCapacity(Seqlist*list)
{
	if (list == NULL)
	{
		cout << "传入为空指针" << endl;
		return -1;
	}
	TSeqlist*tlist = (TSeqlist*)list;
	return tlist->capacity;
}


//顺序表插入元素
int SeqlistInsert(Seqlist*list, SeqlistNode*node, int pos)
{
	int ret = 0;
	TSeqlist*tlist = (TSeqlist*)list;

	//输入不合法
	if (list == NULL || node == NULL || pos < 0)
	{
		ret = -1;
		cout << "输入不合法 list == NULL || node == NULL || pos < 0 " << ret << endl;
		return ret;
	}
	//顺序表已经满了
	if (tlist->len == tlist->capacity)
	{
		ret = -2;
		cout << "顺序表已经满了 tlist->len == tlist->capacity " << ret << endl;
		return ret;
	}
	//顺序表没有满 插入位置大于len 即1到4 插到6、位置5空了
	if (pos >= tlist->len)
	{
		 pos = tlist->len;
	}
	//移动后面元素
	for (int i = tlist->len; i > pos; i--)
	{
		tlist->node[i] = tlist->node[i-1];
	}
	//插入元素
	tlist->node[pos] = (unsigned int*)node;//指针赋给指针
	//若node为一级指针 则(unsigned int)将指针node转换为unsigned int型变量
	tlist->len++;
	return ret;
}

//读取节点
SeqlistNode* SeqlistGet(Seqlist*list, int pos)
{
	SeqlistNode* ret = NULL;
	TSeqlist*tlist = (TSeqlist*)list;

	//输入不合法
	if (list == NULL ||pos < 0 )
	{
		cout << "输入不合法 list == NULL || node == NULL || pos < 0" << ret << endl;
		return ret;
	}
	 ret = (SeqlistNode*)( tlist->node[pos]);
	 return ret;
}

//删除节点
SeqlistNode*SeqlistDelete(Seqlist*list, int pos)
{
	SeqlistNode* ret = NULL;
	TSeqlist*tlist = (TSeqlist*)list;

	//输入不合法
	if (list == NULL || pos < 0)
	{
		cout << "输入不合法 list == NULL || node == NULL || pos < 0 " << ret << endl;
		return ret;
	}
	//移动后面元素
	ret = (SeqlistNode*)(tlist->node[pos]);
	for (int i = pos+1; i <tlist->len; i++)
	{
		tlist->node[i-1] = tlist->node[i];
	}
	tlist->len--;
	return (SeqlistNode*)ret;
}

测试程序 main()

#include"dm_02_seqlist.h"
#include"iostream"
#define _CRT_SECURE_NO_WARNINGS

using namespace std;
//SeqlistNode 为 void根本不不关心节点长啥样
//实际应用时(Teacher*) (SeqlistNode*)进行类型转换 顺序表和业务分离
struct Teacher {
	int age;
	char name[32];
};

void main02()
{ 
	int size = 20;
	int ret = 0;
	Seqlist*list = NULL;
	Teacher t1, t2, t3, t4;
	strcpy(t1.name, "zhangsan22");
	strcpy(t2.name, "lisi22");
	strcpy(t3.name, "wangwu22");
	strcpy(t4.name, "maliu22");
	t1.age = 20;
	t2.age = 22;
	t3.age = 24;
	t4.age = 26;
	//建立链表
	list = SeqlistCreat(10);
	if (list == NULL)
	{
		ret = -1;
		cout << "func SeqlistCreat err" << ret << endl;
		return;//跳出main()函数
	}

	//头插
	ret = SeqlistInsert(list,( SeqlistNode*)&t1, 0);//链表不关心具体的节点是啥(void),用到具体类型进行强制类型转换
	ret = SeqlistInsert(list, (SeqlistNode*)&t2, 0);
	ret = SeqlistInsert(list, (SeqlistNode*)&t3, 0);
	ret = SeqlistInsert(list, (SeqlistNode*)&t4, 0);
	if (list == NULL)
	{
		ret = -1;
		cout << "func SeqlistInsert err" << ret << endl;
		return;
	}

	//遍历
	for (int i = 0; i < SeqlistLength(list); i++)
	{
		Teacher *tmp = (Teacher*)SeqlistGet(list, i);//上层应用知道自己传的是Teacher,别人不知道什么类型,
		if (tmp == NULL)
		{
			ret = -2;
			cout << "func SeqlistGet err" << ret << endl;
			return;
		}
		cout<<tmp->name<< tmp->age << endl;
	}
	//删除
	while (SeqlistLength(list)>0)
	{ 
		Teacher*tmp = NULL;
		tmp = (Teacher*)SeqlistDelete(list, 0);//删0位置 即头
		if (tmp == NULL)
		{
			ret = -3;
			cout << "func SeqlistDelete err" << ret << endl;
			return;
		}
		cout << tmp->name << '\t' << tmp->age << endl;
	}

         //检验是否删除完毕
	for (int i = 0; i < SeqlistLength(list); i++)
	{
		Teacher *tmp = (Teacher*)SeqlistGet(list, i);//上层应用知道自己传的是Teacher,别人不知道什么类型,
		if (tmp == NULL)
		{
			ret = -2;
			cout << "func SeqlistGet err" << ret << endl;
			return;
		}
		cout << tmp->name << tmp->age << endl;
	}


}

测试结果:

基于顺序表的栈:


栈的头文件:

#pragma once
#ifndef  __MY_SEQSTACK_H__ 
#define  __MY_SEQSTACK_H__

typedef void SeqStack;
typedef void SeqNode;

SeqStack* SeqStack_Create(int capacity);
void SeqStack_Destroy(SeqStack * stack);
void SeqStack_Clear(SeqStack * stack);
void SeqStack_Push(SeqStack * stack, SeqNode*item);
SeqNode* SeqStack_Pop(SeqStack * stack);
SeqNode* SeqStack_Top(SeqStack * stack);
int SeqStack_Size(SeqStack * stack);
int SeqStack_Capacity(SeqStack * stack);
#endif  //__MY_SEQLIST_H__



栈的实现文件:

#include"iostream"
#include"dm_06_seqStack.h"

using namespace std;
struct TseqStack {
	int len;
	int capacity;
	unsigned int **node;
};

//栈是特殊的线性表 创建栈相当于创建线性表
SeqStack* SeqStack_Create(int capacity)
{
	if (capacity <= 0)
	{
		cout << "SeqStack_Create err capacity <= 0 " << endl;
		return NULL;
	}
	TseqStack *tseqStack = (TseqStack *)malloc(sizeof(TseqStack));
	memset(tseqStack, 0, sizeof(tseqStack));
	tseqStack->node = (unsigned int **)(malloc(sizeof(unsigned int *)*capacity));
	tseqStack->capacity = capacity;
	tseqStack->len = 0;
	return tseqStack;
}
//销毁栈
void SeqStack_Destroy(SeqStack * stack)
{
	if (stack == NULL)
	{
		cout << "SeqStack_Destroy err stack == NULL " << endl;
	}
	else
	{
		TseqStack *tseqStack = (TseqStack *)(stack);
		tseqStack->capacity = 0;
		tseqStack->len = 0;
		if (tseqStack != NULL)
		{
			free(tseqStack);
		}
	}
}
//清空栈 等价于清空线性表
void SeqStack_Clear(SeqStack * stack)
{
	if (stack == NULL)
	{
		cout << "SeqStack_Clear err stack == NULL " << endl;
	}
	else
	{
		TseqStack *tseqStack = (TseqStack *)(stack);
		tseqStack->capacity = 0;
		tseqStack->len = 0;
		tseqStack = NULL;
	}
}
//压栈 相当于线性表尾插法
void SeqStack_Push(SeqStack * stack, SeqNode*item)
{
	if (stack == NULL|| item == NULL)
	{
		cout << "SeqStack_Push err stack == NULL|| item == NULL" << endl;
	}
	else
	{
		TseqStack *tseqStack = (TseqStack *)(stack);
		if (tseqStack->len >= tseqStack->capacity)
		{
			cout << "SeqStack_Push err tseqStack->len >= tseqStack->capacity" << endl;
		}
		else
		{
			tseqStack->len++;//必须先加1 否则len为0则下一步无法读
			tseqStack->node[tseqStack->len-1] = (unsigned int*)item;//下标从0开始,所以len-1
			
		}
	}
}

//弹栈 相当于从线性表尾部删除
SeqNode* SeqStack_Pop(SeqStack * stack)
{
	TseqStack *tseqStack = (TseqStack *)(stack);
	SeqNode* ret = NULL;
	if (tseqStack == NULL)
	{
		cout << "SeqStack_Pop err stack == NULL" << endl;
		return ret;
	}
	else
	{
		ret = (SeqNode*)tseqStack->node[tseqStack->len - 1];
		tseqStack->len--;
		return ret;
	}
}
//获取站顶元素 相当于从线性表尾部读取
SeqNode* SeqStack_Top(SeqStack * stack)
{
	TseqStack *tseqStack = (TseqStack *)(stack);
	SeqNode* ret = NULL;
	if (tseqStack == NULL)
	{
		cout << "SeqStack_Top err stack == NULL" << endl;
		return ret;
	}
	else
	{
		ret = (SeqNode*)tseqStack->node[tseqStack->len - 1];
		return ret;
	}
}
int SeqStack_Size(SeqStack * stack)
{
	int ret = 0;
	TseqStack *tseqStack = (TseqStack *)(stack);
	if (tseqStack == NULL)
	{
		cout << "SeqStack_Size err stack == NULL" << endl;
		return ret;
	}
	else
	{
		ret = tseqStack->len;
		return ret;
	}
}
int SeqStack_Capacity(SeqStack * stack)
{
	int ret = 0;
	TseqStack *tseqStack = (TseqStack *)(stack);
	if (tseqStack == NULL)
	{
		cout << "SeqStack_Size err stack == NULL" << endl;
		return ret;
	}
	else
	{
		ret = tseqStack->capacity;
		return ret;
	}
}


栈的测试文件:

#include"dm_06_seqStack.h"
#include"iostream"

using namespace std;

struct Teacher_06 {
	int age;
	char name[32];
};

void main()
{
	SeqStack*stack;
	Teacher_06 t1, t2, t3, t4;
	strcpy(t1.name, "zhangsan66");
	strcpy(t2.name, "lisi66");
	strcpy(t3.name, "wangwu66");
	strcpy(t4.name, "maliu66");
	t1.age = 20;
	t2.age = 22;
	t3.age = 24;
	t4.age = 26;

	stack = SeqStack_Create(10);
	SeqStack_Push(stack, (SeqNode*)(&t1));
	SeqStack_Push(stack, (SeqNode*)(&t2));
	SeqStack_Push(stack, (SeqNode*)(&t3));
	SeqStack_Push(stack, (SeqNode*)(&t4));

	cout<<"stack_size"<<SeqStack_Size(stack)<<endl;
	cout << "stack_capicity" << SeqStack_Capacity(stack) << endl;
	Teacher_06 * tmp = (Teacher_06 *)SeqStack_Top(stack);
	cout<<"stackTop"<< tmp->name<<" "<<tmp->age<<endl;


	//弹栈 遍历
	int len =  SeqStack_Size(stack);
	for (int i = 0; i<len ; i++)
	{
		tmp = (Teacher_06 *)SeqStack_Pop(stack);
		cout << tmp->name << " " << tmp->age << endl;
	}

	system("pause");
}


栈的测试结果:


基于顺序表的队列:


队列的头文件:

#pragma once//包含一次 若被多个cpp文件包含则会导致在多个文件里重复编译出错
#include"iostream"
#include"dm_02_seqlist.h"


typedef void SeqQueue;

SeqQueue* SeqQueue_Create(int capacity);

void SeqQueue_Destroy(SeqQueue* queue);

void SeqQueue_Clear(SeqQueue* queue);

int SeqQueue_Append(SeqQueue* queue, void* item);

void* SeqQueue_Retrieve(SeqQueue* queue);

void* SeqQueue_Header(SeqQueue* queue);

int SeqQueue_Length(SeqQueue* queue);

int SeqQueue_Capacity(SeqQueue* queue);




队列的实现文件:

#include"iostream"
#include"dm_08_seqqueue.h"


Seqlist* SeqlistCreat(int capacity);
void SeqlistDestory(Seqlist*list);
void SeqlistClear(Seqlist*list);
int SeqlistLength(Seqlist*list);
int SeqlistCapacity(Seqlist*list);
int SeqlistInsert(Seqlist*list, SeqlistNode*node, int pos);
SeqlistNode* SeqlistGet(Seqlist*list, int pos);
SeqlistNode*SeqlistDelete(Seqlist*list, int pos);


SeqQueue* SeqQueue_Create(int capacity)
{
	return  SeqlistCreat( capacity);
}

void SeqQueue_Destroy(SeqQueue* queue)
{
	SeqlistDestory((Seqlist*)(queue));
}

void SeqQueue_Clear(SeqQueue* queue)
{
	SeqlistClear((Seqlist*)(queue));
}

int SeqQueue_Append(SeqQueue* queue, void* item)
{
	int ret = -1;
	ret = SeqlistInsert((Seqlist*)(queue), (SeqlistNode*)(item), SeqQueue_Length(queue));//len比下标大1 插入位置为尾部下标后的一个位置刚好是len
	if (ret != 0)
	{
		cout << "SeqQueue_Append err ret" << ret << endl;
	}
	return ret;
}
//出队列相当于从线性表中删除0号位置元素
void* SeqQueue_Retrieve(SeqQueue* queue)
{
	SeqlistNode*ret = SeqlistDelete((Seqlist*)(queue),0);
	if (ret == NULL)
	{
		cout << "SeqQueue_Retrieve err" << endl;
	}
	return (void*)ret;
}
//获取队列头部   相当于从线性表中获取0号元素
void* SeqQueue_Header(SeqQueue* queue)
{
	SeqlistNode*ret = SeqlistGet((Seqlist*)(queue), 0);
	if (ret == NULL)
	{
		cout << "SeqQueue_Header err" << endl;
	}
	return (void*)ret;
}
//相当于获取线性表长度
int SeqQueue_Length(SeqQueue* queue)
{
	return SeqlistLength((Seqlist*)(queue));
}

int SeqQueue_Capacity(SeqQueue* queue)
{
	return  SeqlistCapacity((Seqlist*)(queue));
}




队列的测试文件:

#include"iostream"
#include"dm_08_seqqueue.h"

using namespace std;
struct Teacher_08 {
	int age;
	char name[32];
};


void main()
{
	SeqQueue*seqqueue;
	Teacher_08 t1, t2, t3, t4;
	strcpy(t1.name, "zhangsan66");
	strcpy(t2.name, "lisi66");
	strcpy(t3.name, "wangwu66");
	strcpy(t4.name, "maliu66");
	t1.age = 20;
	t2.age = 22;
	t3.age = 24;
	t4.age = 26;

	seqqueue = SeqQueue_Create(4);

	SeqQueue_Append(seqqueue, (void*)(&t1));
	SeqQueue_Append(seqqueue, (void*)(&t2));
	SeqQueue_Append(seqqueue, (void*)(&t3));
	SeqQueue_Append(seqqueue, (void*)(&t4));

	//队列的属性
	cout << "seqqueue_capacity" << SeqQueue_Capacity(seqqueue) << endl;
	cout << "seqqueuesize" << SeqQueue_Length(seqqueue) << endl;
	Teacher_08 * tmp = (Teacher_08 *)SeqQueue_Header(seqqueue);
	cout << "seqqueue header" << tmp->name << " " << tmp->age << endl;


	//出队遍历
	int len = SeqQueue_Length(seqqueue);
	for (int i = 0; i<len; i++)
	{
		tmp = (Teacher_08 *)SeqQueue_Retrieve(seqqueue);
		cout << tmp->name << " " << tmp->age << endl;
	}
	system("pause");
}


队列的测试结果:

第一次写博客,Mark一下,督促记录自己学习吧。

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值