本次实现了一个顺序表,该顺序表具有如下功能:
(1)初始化一个空顺序表,初始顺序表长度可自定义;
(2)查找某个元素在顺序表中第一次出现的位置,如果不存在返回0;
(3)查找某个元素在顺序表中出现的次数;
(4)求当前顺序表的长度;
(5)在顺序表L中的第i个位置前插入新元素e;
(6)在顺序线性表L中删除第i个元素,用e返回其值;
(7)获取顺序表指定位置的元素值;
(8)给顺序表指定位置元素赋值.
#include <iostream>
#include <cstdio>
#include <cstdlib> //若在CodeBlocks中如果使用malloc(),realloc(),需要包含该头文件
using namespace std;
#define OK 1
#define ERROR 0
#define OVERFLOW -1
#define List_INIT_SPACE 100 //存储控件初始分配量
#define List_INC_SPACE 50 //存储控件分配增量
typedef int ElementType; //指定顺序表中数据类型
typedef struct {
ElementType *elem;
int length;
int listsize;
}List;
#pragma mark - 1.初始化一个空顺序表,初始顺序表长度为100
/****--------------------------------------------------------****/
//函数名: ListInit(List &L)
//参数: (传入) List L, 顺序表结构体 L, 存储线性表相关消息(&相当于传入 L 的地址)
//返回值: int 型,返回1标识创建成功,0表示失败
//功能: 初始化一个空顺序表
/****--------------------------------------------------------****/
int listInit(List &L)
{
//在内存中分配空间
//L.elem = (ElementType*)malloc(List_INIT_SPACE * sizeof(ElementType));
L.elem = new ElementType[List_INIT_SPACE];
//存储分配失败
if (!L.elem) {
exit(OVERFLOW);
}
//构造一个空的线性表 L
L.length = 0;
//初始存储容量
L.listsize = List_INIT_SPACE;
return OK;
}
#pragma mark - 2.查找某个元素在顺序表中第一次出现的位置,如果不存在返回0
/****--------------------------------------------------------****/
//函数名: locateElem(List L, ElementType e)
//参数: (传入)List L,顺序表
// (传入)ElementType e,定位元素
//返回值: int型,返回定位元素位置,0表示失败
//功能: 在顺序表中定位元素
/****--------------------------------------------------------****/
int listLocateElem(List L, int e)
{
int i = 0;
//定义线性表指针
int *p = L.elem;
//查找元素e
while (i < L.length && *p != e) {
i++;
p++;
}
if (i <= L.length) {
return i;
}else {
return ERROR;
}
}
#pragma mark - 3.查找某个元素在顺序表中出现的次数
/****--------------------------------------------------------****/
//函数名: listExistTimes(List L, ElementType e)
//参数: (传入)List L,顺序表
// (传入)ElementType e,需要查找的元素
//返回值: int型,返回定位元素在顺序表中出现的次数,0表示不存在
//功能: 在顺序表中定位元素
/****--------------------------------------------------------****/
int listExistTimes(List L, int e)
{
int i = 0;
int sum = 0;
//定义线性表指针
int *p = L.elem;
//查找元素e
while (i < L.length) {
p = &L.elem[i];
if ( *p == e) {
sum++;
}
i++;
p++;
}
return sum;
}
#pragma mark - 4.求当前顺序表的长度
/* 求顺序表的长度*/
int listGetLength(List L)
{
return L.length;
}
#pragma mark - 5.在顺序表L中的第i个位置前插入新元素e
/****--------------------------------------------------------****/
//函数名: listInsert(List &L, int i, ElementType e)
//参数: (传入) List &L 顺序表
// (传入) int i 插入位置
// (传入)ElementType e 插入元素
//返回值: 1表示成功, 0表示操作失败
//功能: 在顺序表L中的第i个位置前插入新元素e
//备注: i的合法取值为0 <= i <= 线性表的长度
/****--------------------------------------------------------****/
int listInsert(List &L, int i, ElementType e)
{
//判断位置是否合法
if (i < 0 || i > L.length) {
cout << "i的值不合法!" << endl;
return 0;
}
//超出空间进行再分配
if (L.length >= L.listsize) {
int *newSpace;
newSpace = (ElementType*) realloc(L.elem, (L.listsize + List_INC_SPACE) * sizeof(ElementType));
//存储空间分配失败
if (!newSpace) {
exit(OVERFLOW);
}
//新基址
L.elem = newSpace;
//增加存储容量
L.listsize = L.listsize + List_INC_SPACE;
}
//定义指向线性表位置i和尾的指针
int *p, *q;
//q指针指向插入位置i
q = &(L.elem[i]);
for (p = &(L.elem[L.length - 1]); p >= q; p--) {
*(p + 1) = *p; //插入元素之后的元素右移
}
*q = e; //把元素e放在位置i处
L.length++; //线性表长度增加1
return OK;
}
#pragma mark - 6.在顺序线性表L中删除第i个元素,用e返回其值
/****--------------------------------------------------------****/
//函数名: ListDelete(List &L, int i, ElementType &e)
//参数: (传入)List &L 顺序表
// (传入)int i 删除位置
// (传出)ElementType &e 删除元素
//返回值: 1表示成功, 0表示失败
//功能:在顺序线性表L中删除第i个元素,用e返回其值
//备注: i的合法取值为 0 <= i < 线性表长度( 0 <= i < L.length)
/****--------------------------------------------------------****/
int listDelete(List &L, int i, ElementType &e)
{
//判断位置是否合法
if (i < 0 || i > L.length - 1) {
cout << "i的值不合法" << endl;
return 0;
}
int *p, *q; //定义指向线性表位置i和尾的指针
p = &(L.elem[i]); //p为被删除元素的位置
e = *p;
q = L.elem + L.length - 1; //q指针指向线性表最有一个元素
for (; p < q; p++) {
*p = *(p + 1); //被删除元素之后的元素左移
}
L.length--;
return OK;
}
#pragma mark - 7.获取顺序表指定位置的元素值
/****--------------------------------------------------------****/
//函数名: listGetValue(List &L, int n)
//参数: (传入) List &L 顺序表
// (传入) int n 要获取元素的位置下标
//返回值: 要获取的元素
//功能: 获取顺序表指定位置的元素值
//备注: i的合法取值为0<= i < 线性表的长度
/****--------------------------------------------------------****/
ElementType listGetSpecifiedValue(List &L, int n)
{
//定义线性表指针
ElementType *p = &(L.elem[n]);
//获取指定位置元素的值
return *p;
}
#pragma mark - 8.给顺序表指定位置元素赋值
/****--------------------------------------------------------****/
//函数名: listAssignValue(List &L,int i, int value)
//参数: (传入) List &L 顺序表
// (传入) int i 赋值位置下标
// (传入) int value 指定位置要赋予的值
//功能: 给顺序表指定位置元素赋值
//备注: i的合法取值为0<= i < 线性表的长度
/****--------------------------------------------------------****/
void listAssignValue(List &L, int i, ElementType value)
{
//定义线性表指针
ElementType *p = &(L.elem[i]);
*p = value;
}
#pragma mark - 主函数
/****------------------------测试程序----------------------------****/
int main(int argc, const char * argv[]) {
List R; //实参定义
int flag;
//为了判断调用成功与否,可以检查flag的值,或者见插入操作的调用方法
//if(flag == 1) cout << "成功";
//else cout << "失败";
flag = listInit(R);
//调用方法
//向顺序表中插入0~9,共10个数
for (int i = 0; i < 10; i++) {
listInsert(R, i, i);
}
//输出顺序表中的所有元素
for (int i = 0; i < R.length; i++) {
cout << listGetSpecifiedValue(R, i) << " ";
}
cout << endl;
//在顺序表表头插入元素34
listInsert(R, 0, 34);
//输出顺序表中的所有元素
for (int i = 0; i < R.length; i++) {
cout << listGetSpecifiedValue(R, i) << " ";
}
cout << endl;
//在顺序表表尾插入元素345
listInsert(R, R.length, 345);
//输出顺序表中的所有元素
for (int i = 0; i < R.length; i++) {
cout << listGetSpecifiedValue(R, i) << " ";
}
cout << endl;
//在顺序表表尾插入元素345
listInsert(R, R.length, 345);
//输出顺序表中的所有元素
for (int i = 0; i < R.length; i++) {
cout << listGetSpecifiedValue(R, i) << " ";
}
cout << endl;
//输出345在顺序表中出现的次数.
cout << listExistTimes(R, 345) << endl;
int x;
//删除第0个元素
listDelete(R, 0, x);
//输出顺序表中的所有元素
for (int i = 0; i < R.length; i++) {
cout << listGetSpecifiedValue(R, i) << " ";
}
cout << endl;
//删除顺序表最有一个元素
listDelete(R, R.length-1, x);
//输出顺序表中的所有元素
for (int i = 0; i < R.length; i++) {
cout << listGetSpecifiedValue(R, i) << " ";
}
cout << endl;
return 0;
}