顺序表的基本操作和几道常见面试题总结

定义顺序表

typedef int DataType;
#define MAX 100

//定义顺序表
typedef struct SeqList
{
    DataType data[MAX];
    int sz;//标识顺序表里边现在有多少个元素
}SeqList,*pSeqList;

顺序表的接口

//初始化顺序表
void InitSeqList(pSeqList ps);
//尾部插入
void PushBack(pSeqList ps, DataType data);
//尾部删除
void PopBack(pSeqList ps);
//头部插入
void PushFront(pSeqList ps, DataType data);
//头部删除
void PopFront(pSeqList ps);
//查找指定元素
int Find(pSeqList ps, DataType data);
//在指定位置插入指定元素
void Insert(pSeqList ps, DataType data, int pos);
//删除指定位置的元素
void Erase(pSeqList ps, int pos);
//删除指定元素
void Remove(pSeqList ps, DataType data);
//删除指定的所有元素
void RemoveAll(pSeqList ps, DataType data);
//顺序表的大小
int Size(pSeqList ps);
//判断顺序表是否为空
int Empty(pSeqList ps);
//对顺序的元素进行冒泡排序
void BubbleSort(pSeqList ps);
//选择排序
void SelectSort(pSeqList ps);
//优化选择排序(最小值和最大值)
void SelectSort_op(pSeqList ps);
//二分查找指定元素
int BinarySearch(pSeqList ps, DataType data);
//递归二分查找
int BinarySearch_D(pSeqList ps, int left,int right,DataType data);
//打印顺序表
void PrintSeqList(pSeqList ps);

接口的实现

#include"seqlist.h"
//初始化顺序表
void InitSeqList(pSeqList ps)
{
    assert(ps != NULL);
    ps->sz = 0;
    memset(ps->data, 0, sizeof(ps->data));
}
//尾插一个元素
void PushBack(pSeqList ps, DataType data)
{
    assert(ps != NULL);
    if (ps->sz == MAX)
    {
        printf("顺序表已满,不能插入\n");
        return;
    }
    ps->data[ps->sz] = data;
    ps->sz++;
}
//尾删一个元素
void PopBack(pSeqList ps)
{
    assert(ps != NULL);
    if (ps->sz == 0)
    {
        printf("顺序表为空,不能删除\n");
        return;
    }
    ps->sz--;
}
//打印顺序表
void PrintSeqList(pSeqList ps)
{
    assert(ps != NULL);
    int i = 0;
    if (ps->sz == 0)
    {
        printf("顺序表为空");
    }
    for (i = 0; i < ps->sz; i++)
    {
        printf("%d ", ps->data[i]);
    }
    printf("\n");
}
//前插一个元素
void PushFront(pSeqList ps, DataType data)
{
    int i = 0;
    assert(ps != NULL);
    if (ps->sz == MAX)
    {
        printf("顺序表已满,不能插入\n");
        return;
    }
    for (i = ps->sz - 1; i >= 0; i--)
    {
        ps->data[i + 1] = ps->data[i];
    }
    ps->data[0] = data;
    ps->sz++;
}
//头删一个元素
void PopFront(pSeqList ps)
{
    int i = 0;
    assert(ps != NULL);
    if (ps->sz == 0)
    {
        printf("顺序表为空,不能删除\n");
        return;
    }
    for (i = 0; i < ps->sz - 1; i++)
    {
        ps->data[i] = ps->data[i + 1];
    }
    ps->sz--;
}
//查找指定元素,找到返回下标,找不到返回-1
int Find(pSeqList ps, DataType data)
{
    int i = 0;
    assert(ps != NULL);
    for (i = 0; i < ps->sz; i++)
    {
        if (ps->data[i] == data)
        {
            return i;
        }
    }
    return -1;
}
//指定位置前插入一个元素
void Insert(pSeqList ps, DataType data, int pos)
{
    int i = 0;
    assert(ps != NULL);
    assert(pos >= 0 && pos <= ps->sz);//断言插入位置的合法性
    if (ps->sz == MAX)
    {
        printf("顺序表已满,不能插入\n");
        return;
    }
    for (i = ps->sz - 1; i >= pos; i--)
    {
        ps->data[i + 1] = ps->data[i];
    }
    ps->data[pos] = data;
    ps->sz++;
}
//指定位置删除一个元素
void Erase(pSeqList ps, int pos)
{
    int i = 0;
    assert(ps != NULL);
    assert(pos >= 0 && pos < ps->sz);//断言删除位置的合法性
    if (ps->sz == 0)
    {
        printf("顺序表为空,不能删除\n");
        return;
    }
    for (i = pos; i < ps->sz - 1; i++)
    {
        ps->data[i] = ps->data[i + 1];
    }
    ps->sz--;
}
//移除指定的元素(只移除第一次找到的元素)
void Remove(pSeqList ps, DataType data)
{
    int i = 0;
    assert(ps != NULL);
    if (ps->sz == 0)
    {
        printf("顺序表为空\n");
        return;
    }
    for (i = 0; i < ps->sz; i++)
    {
        if (ps->data[i] == data)
        {
            break;
        }
    }
    if (i == ps->sz)
    {
        printf("没有要删除的元素\n");
        return;
    }
    for (; i < ps->sz - 1; i++)
    {
        ps->data[i] = ps->data[i + 1];
    }
    ps->sz--;
}
//删除所有指定的元素
void RemoveAll(pSeqList ps, DataType data)
{
    int i = 0;
    int pos = 0;
    int count = 0;
    assert(ps != NULL);
#if 0
    while ((pos = Find(ps, data)) != -1)
    {
        Erase(ps, pos);
    }
#endif
#if 0
    for (i = 0; i < ps->sz; i++)
    {
        if (ps->data[i] == data)
        {
            int j = i;
            for (; j < ps->sz - 1; j++)
            {
                ps->data[j] = ps->data[j + 1];
            }
            ps->sz--;
            i--;
            //只要删除一个元素,就一定要将i减1,否则会跳过去一个元素
        }
    }
#endif
#if 0
    DataType *tmp = malloc(sizeof(DataType)*ps->sz);
    for (i = 0; i < ps->sz; i++)
    {
        if (ps->data[i] != data)
        {
            tmp[count++] = ps->data[i];
        }
    }
    memcpy(ps->data, tmp, sizeof(DataType)*count);
    ps->sz = count;
    free(tmp);
    tmp = NULL;
#endif
    for (i = 0; i < ps->sz; i++)
    {
        if (ps->data[i] != data)
        {
            ps->data[count++] = ps->data[i];
        }
    }//用两个下标控制data数组,将不等于指定数据的元素重新覆盖已有元素
    ps->sz = count;
}
//求顺序表长度
int Size(pSeqList ps)
{
    return ps->sz;
}
//判断顺序表是否为空
int Empty(pSeqList ps)
{
    //非空返回0,空返回1
    return ps->sz == 0;
}
static Swap(DataType *ps1, DataType *ps2)
{
    DataType tmp = 0;
    tmp = *ps1;
    *ps1 = *ps2;
    *ps2 = tmp;
}
//将顺序表的元素进行冒泡排序
void BubbleSort(pSeqList ps)
{
    assert(ps != NULL);
    int i = 0;
    int flag = 0;
    for (i = 0; i < ps->sz - 1; i++)//确定排序趟数
    {
        int j = 0;
        for (j = 0; j < ps->sz - 1 - i; j++)//一趟排序完少一个比较的元素
        {
            flag = 0;
            if (ps->data[j]>ps->data[j + 1])
            {
                Swap(ps->data + j, ps->data + j + 1);
                flag = 1;
            }
        }
        if (flag == 0)
        {
            return;
        }
    }
}
//对顺序表的元素选择排序
void SelectSort(pSeqList ps)
{
    assert(ps != NULL);
    int i = 0;
    for (i = 0; i < ps->sz - 1; i++)
    {
        int j = 0;
        //max为最大元素的下标
        int max = 0;
        for (j = 1; j < ps->sz - i; j++)
        {
            if (ps->data[max] < ps->data[j])
            {
                max = j;
            }
        }
        if (max != ps->sz - 1 - i)
        {
            Swap(ps->data + max, ps->data + ps->sz - 1 - i);
        }
    }
}
//选择排序优化
void SelectSort_op(pSeqList ps)
{
    int start = 0;
    int end = ps->sz - 1;
    assert(ps != NULL);
    while (start < end)
    {
        int max = start;
        int min = start;
        int i = 0;
        for (i = start; i <= end; i++)
        {
            if (ps->data[max] < ps->data[i])
            {
                max = i;
            }
            if (ps->data[min]>ps->data[i])
            {
                min = i;
            }
        }
        if (min != start)
        {
            Swap(ps->data + start, ps->data + min);
        }
        if (max == start)
        {
            max = min;
        }//如果max等于min,最小值已经被交换,所以要找到最大值,必须改变下标
        if (max != end)
        {
            Swap(ps->data + max, ps->data + end);
        }
        start++;
        end--;
    }
}
二分查找指定元素
int BinarySearch(pSeqList ps, DataType data)
{
    int left = 0;
    int right = ps->sz - 1;
    while (left <= right)
    {
        int mid = left + ((right - left) / 2);
        if (ps->data[mid] > data)
        {
            right = mid - 1;
        }
        else if (ps->data[mid] < data)
        {
            left = mid + 1;
        }
        else
        {
            return mid;
        }
    }
    return -1;
}
//递归二分查找
int BinarySearch_D(pSeqList ps, int left, int right, DataType data)
{
    int mid = 0;
    if (left > right)
    {
        return -1;
    }
    mid = left + ((right - left) / 2);
    if (ps->data[mid] > data)
    {
        return BinarySearch_D(ps, left, mid - 1, data);
    }
    else if (ps->data[mid] < data)
    {
        return BinarySearch_D(ps, mid + 1, right, data);
    }
    else
    {
        return mid;
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值