顺序链表没什么说的啦,直接上代码,参考了传智播客出版的数据结构。创建工程的时候不小心弄成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;
}