顺序链表C语言实现

顺序链表没什么说的啦,直接上代码,参考了传智播客出版的数据结构。创建工程的时候不小心弄成c++了,不过没关系,都一样。

Operation中有一处语法上的疑惑,就是插入的那个函数中,node为什么要强制转换成整型,既然等式两边都是指针,为什么不是转化成int* ,有心人帮忙解答一下,谢谢。

SeqList.h头文件

#ifndef _SEQLIST_H_
#define _SEQLIST_H_

typedef void SeqList;
typedef void SeqListNode;

/*
顺序存储线性表操作
创建-Create()
初始化-Init()
获取长度-GetLength()
判断表是否为空-IsEmpty()
获取元素-Get()
插入-Insert()
删除-Delete()
清空表-Clear()
*/

SeqList* SeqList_Create(int capacity);
void SeqList_Destory(SeqList *list);
void Seqlist_Clear(SeqList * list);
int SeqList_Length(SeqList * list);
int SeqList_Capacity(SeqList * list);
int SeqList_Insert(SeqList * list,SeqListNode * node,int pos);
SeqList * SeqList_Get(SeqList *list, int pos);
SeqList * SeqList_Delete(SeqList * list, int pos);

#endif

Operation.cpp

/*
顺序存储线性表操作
创建-Create()
初始化-Init()
获取长度-GetLength()
判断表是否为空-IsEmpty()
获取元素-Get()
插入-Insert()
删除-Delete()
清空表-Clear()
思路:创建一个头节点存储线性表的容量、长度、首地址等信息,顺序线性表的优点是可以随机访问
缺点是插入删除等操作效率较低。
*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include "SeqList.h"
typedef struct _tag_SeqList//定义一个头结点
{
	int capacity;
	int length;
	int * node;
}TSeqList;

//创建顺序表
SeqList * SeqList_Create(int capacity)//返回值是void类型的指针,可以用任何类型的指针接住,但是需要强制类型转换
{
	int ret;
	TSeqList *temp = NULL;//声明一个指向头结点的指针
	temp = (TSeqList*)malloc(sizeof(TSeqList));//为头结点分配空间
	if (temp == NULL)//健壮性保护,每次malloc后都要判断是否malloc成功,养成好习惯
	{
		ret = 1;
		printf("func SeqList_Create() error:%d\n", ret);
		return NULL;
	}
	memset(temp, 0, sizeof(TSeqList));//初始化将temp指向处到TSeqList个字节的内容置为0
	temp->capacity = capacity;
	temp->length = 0;
	temp->node = (int *)malloc(sizeof(void *) * capacity);//指针不管什么类型,实际上大小都是一样的,所以参数表出用void *。
	if (temp->node == NULL)
	{
		ret = 2;
		printf("func SeqList_Create() error:%d\n", ret);
		return NULL;
	}
    return temp;
}

int SeqList_Capacity(SeqList * list)//传入的参数是万能指针void类型的,可以用任何类型的指针接着,但是需要强制转换,非常灵活
{
	TSeqList *temp = NULL;
	if (list == NULL)//健壮性判断
	{
		return -1;
	}
	temp = (TSeqList *)list;//因为传入的万能指针,所以要做个强制类型转化
	return temp->capacity;
}

int SeqList_Length(SeqList * list)//传入的参数是万能指针void类型的,可以用任何类型的指针接着,但是需要强制转换,非常灵活
{
	TSeqList *temp = NULL;
	if (list == NULL)//健壮性判断
	{
		return -1;
	}
	temp = (TSeqList *)list;//因为传入的万能指针,所以要做个强制类型转化
	return temp->length;
}

int SeqList_Insert(SeqList *list, SeqListNode * node, int pos)
{
	int i;
	TSeqList *temp = NULL;
	if (list == NULL || node == NULL)
	{
		return -1;
	}
	temp = (TSeqList*)list;
	//如果顺序表满
	if (temp->length >= temp->capacity)
	{
		return -2;
	}
	if (pos > temp->length)//如果给出的位置超过了顺序表的长度,就填补到顺序表最后一位
		pos = temp->length;
	for (i = temp->length; i > pos; i--)//将插入位置的元素一次向后移动
	{
		temp->node[i] = temp->node[i - 1];
	}
	temp->node[i] = (int)node;//在插入位置插入新元素节点
	//node是一个指针数组,且都是万能指针,所以node[i]应该是一个万能指针的地址,那传入的node也是万能指针,要对它明确化
	//但是为什么是int型呢,应该是指向传入类型的指针,但是又不确定传入类型是什么,只好转成int了? 没太搞懂。
	//printf("%p\n", temp->node[i]);
	temp->length++;
	return 0;
}

SeqList* SeqList_Delete(SeqList* list, int pos)
{
	int i = 0;
	TSeqList * tlist = NULL;
	SeqListNode * temp = NULL;
	tlist = (TSeqList*)list;
	if (list == NULL || pos < 0 || pos >= tlist->capacity)
	{
		printf("SeqList_Delete() error\n");
		return NULL;
	}
	temp = (SeqListNode*)tlist->node[pos];
	for (i = pos + i; i < tlist->length; i++)
	{
		tlist->node[i - 1] = tlist->node[i];
	}
	tlist->length--;
	return temp;
}

SeqList * SeqList_Get(SeqList *list, int pos)
{
	TSeqList * tlist = NULL;
	SeqListNode *temp = NULL;
	tlist = (TSeqList *)list;
	if (list == NULL || pos < 0 || pos >= tlist->capacity)
	{
		printf("SeqList_Get() error\n");
		return NULL;
	}

	temp = (SeqListNode*)tlist->node[pos];
	return temp;
}

void SeqList_Clear(SeqList *list)
{
	TSeqList * temp = NULL;
	if (list == NULL)
	{
		return;
	}
	temp = (TSeqList *)list;
	temp->length = 0;
	memset(temp->node, 0, (temp->capacity * sizeof(void *)));
	return;
}

void SeqList_Destory(SeqList * list)
{
	TSeqList * temp = NULL;
	if (list == NULL)
	{
		return;
	}
	temp = (TSeqList *)list;
	if (temp->node != NULL)
	{
		free(temp->node);
	}
	free(temp);
	return;
}

main.cpp测试函数

#include<stdio.h>
#include<stdlib.h>
#include "SeqList.h"

typedef struct _Teacher
{
	char name[32];
	int age;
}Teacher;

int main()
{
	int ret = 0;
	SeqList * list = NULL;
	Teacher t1, t2, t3, t4, t5;
	t1.age = 31;
	t2.age = 32;
	t3.age = 33;
	t4.age = 34;
	t5.age = 35;
	//创建结点10个
	list = SeqList_Create(10);
	//插入结点
	ret = SeqList_Insert(list, (SeqListNode *)&t1, 0);
	ret = SeqList_Insert(list, (SeqListNode *)&t2, 0);
	ret = SeqList_Insert(list, (SeqListNode *)&t3, 0);
	ret = SeqList_Insert(list, (SeqListNode *)&t4, 0);
	ret = SeqList_Insert(list, (SeqListNode *)&t5, 0);
	//printf("Teacher:%p\n", &t5);

	printf("顺序表容量:%d\n", SeqList_Capacity(list));
	printf("顺序表长度:%d\n", SeqList_Length(list));

	printf("遍历顺序表:\n");
	for (int i = 0; i < SeqList_Length(list); i++)
	{
		Teacher * temp = (Teacher *)SeqList_Get(list, i);
		if (temp == NULL)
		{
			printf("func SeqList_Get() error: %d\n", ret);
			return 0;
		}
		printf("age:%d\n", temp->age);
	}

	//销毁链表
	printf("销毁顺序表时:\n");
	while (SeqList_Length(list) > 0)
	{
		Teacher * temp = (Teacher*)SeqList_Delete(list, 0);//删除头部元素
		if (temp == NULL)
		{
			printf("func SeqList_Get() error %d\n", ret);
			return 0;
		}
		printf("age:%d\n", temp->age);
	}
	SeqList_Destory(list);
	system("pause");
	return 0;
}

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值