顺序表增强

本次实现了一个顺序表,该顺序表具有如下功能:

(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;
}


发布了78 篇原创文章 · 获赞 12 · 访问量 9万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章