本文主要是介绍顺序表的实现(迈入数据结构的大门)(完整代码),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
seqlist.h
#pragma once
typedef int SLDataType;#include<stdio.h>
#include<stdlib.h>
#include<assert.h>typedef struct SeqList
{SLDataType* a;int size; // 有效数据个数int capacity; // 空间容量
}SL;//初始化和销毁
void SLInit(SL* ps);
void SLDestroy(SL* ps);
void SLPrint(SL* ps);
//扩容
void SLCheckCapacity(SL* ps);
//头部插?删除 / 尾部插?删除
void SLPushBack(SL* ps, SLDataType x);
void SLPopBack(SL* ps);
void SLPushFront(SL* ps, SLDataType x);
void SLPopFront(SL* ps);
//指定位置之前插?/删除数据
void SLInsert(SL* ps, int pos, SLDataType x);
void SLErase(SL* ps, int pos);
int SLFind(SL* ps, SLDataType x);
试着自己根据上方头文件,写一篇属于自己的顺序表吧!!!
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include"seqlist.h"//typedef int SLdataTapy;
//#define N 10
//
//typedef struct seqlist {
// SLdataTapy arr[N];//定长数组
// int size;//有效数组个数
//}SL;//typedef int SLdataTapy;
//
//typedef struct seqlist {
// SLdataTapy* a;//用来开辟动态内存
// int size;//有效数组个数
// int capacity;//剩余容量;判断是否需要新添加内存
//}SL;//初始化和销毁
void SLInit(SL* ps) {ps->a = NULL;ps->size = ps->capacity = 0;
}void SLDestroy(SL* ps) {if (ps->a) {//判断数组中是否为空free(ps->a);//因为需要使用malloc,所以需要注意释放内存}ps->a = NULL;ps->size = ps->capacity = 0;
}//扩容
void SLCheckCapacity(SL* ps) {//先要判断内存够不够if (ps->size == ps->capacity) {//使用malloc relloc cellocint newcappacity = ps->capacity == 0 ? 4 :ps->capacity*2;//一般增容原来内存的二到三倍;SLDataType*tmp = (SLDataType*)relloc(ps->a,newcappacity * sizeof(SLDataType));//注:这里没有直接使用ps->a直接申请,是为了防止内存申请失败;防止数据丢失if (tmp == NULL) {//也可以使用assert直接终止程序;需要使用aseert.h的头文件perror("relloc fail");exit(1);//直接退出程序;也可使用return;}//空间增容成功ps->a = tmp;ps->capacity = newcappacity;}
}
//头插
void SLPushFront(SL* ps, SLDataType x) {//记住SLDataType,这里为我们为了方便(typedef int SLDataType)assert(ps);//断言一下,防止指针为空SLCheckCapacity(&ps);//开辟空间int i = ps->size;for (; i > 0; i--);//从后往前移位{ps->a[i] = ps->a[i - 1];}ps->a[0] = x;//此时a[0]就空出来存放x;ps->size++;//不要忘记size需要++
}
//头删
void SLPopFront(SL* ps) {assert(ps);assert(ps->size);//存放的值不能为NULL;for (int i = 0; i < ps->size-1; i++) {ps->a[i] = ps->a[i + 1];}ps->size--;
}
//尾插
void SLPushBack(SL* ps, SLDataType x) {assert(ps);void SLCheckCapacity(SL * ps);ps->a[ps->size++] = x;//相当于ps->a[ps->size] = x;//ps->size++;
}
//尾删
void SLPopBack(SL* ps) {assert(ps);assert(ps->size);//进行尾删,必须存在尾删的值ps->size--;
}//查找
int SLFind(SL* ps, SLDataType x) {assert(ps);for (int i = 0; i < ps->size; i++) {if (ps->a[i] == x) {return i;}}return -1;
}
//指定位置插入
void SLInsert(SL* ps, int pos, SLDataType x) {assert(ps);assert(pos >= 0 && ps->size > pos);//pos必须在含有值之间插入//插入数据:空间够不够SLCheckCapacity(ps);//让pos及之后的数据整体往后挪动一位for (int i = ps->size; i > pos; i--){ps->a[i] = ps->a[i - 1];//a[pos+1] = a[pos]与头插具有相似之处,导致值的覆盖}ps->a[pos] = x;//这里的pos对应,数组下标,如果不对应,则按情况+-;ps->size++;
}
//删除指定位置的数据
void SLErase(SL* ps, int pos)
{assert(ps);assert(pos >= 0 && pos < ps->size);//与头删类似for (int i = pos; i < ps->size - 1; i++){ps->a[i] = ps->a[i + 1];}ps->size--;
}
void SLPrint(SL s)//对于打印数组,这里不再需要传地址,而是传值
{for (int i = 0; i < s.size; i++){//对于结构体的使用 (.)与(->)的不同printf("%d ", s.a[i]);}printf("\n");
}
下一节我们将实现(通讯录)顺序表
这篇关于顺序表的实现(迈入数据结构的大门)(完整代码)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!