C语言实现顺序表

头文件seqlist.h

#ifndef __SEQLIST_H__ 
#define __SEQLIST_H__ 

#include <stdio.h>
#include <assert.h>
#include <stdlib.h>

#define MAX 10 

typedef int DataType; 

typedef struct SeqList 
{ 
DataType data[MAX];
int sz; 
}SeqList, *pSeqList; 

void InitSeqList(pSeqList ps); //初始化
void PushBack(pSeqList ps, DataType d);//尾插 
void PopBack(pSeqList ps); //尾删
void Display(const pSeqList ps); //打印
void PushFront(pSeqList ps, DataType d); //头插
void PopFront(pSeqList ps); //头删
int Find(pSeqList ps, DataType d); //查找
void Insert(pSeqList ps, DataType d, int pos);//指定位置插入 
void Remove(pSeqList ps, DataType d); //删除首次出现的指定数据
void RemoveAll(pSeqList ps, DataType d); //删除顺序表中所有指定数据
void Reverse(pSeqList ps);//逆置顺序表 
void Sort(pSeqList ps); //排序
int BinarySearch(pSeqList ps, DataType d); //二分查找
#endif //__SEQLIST_H__ 

函数实现seqlist.c

#include "seqlist.h"


void InitSeqList(pSeqList ps)//初始化
{
    //断言
    assert(ps);

    ps->sz = 0;
}
void PushBack(pSeqList ps, DataType d)//尾插
{
    //断言
    assert(ps);
    assert(ps->sz<MAX);

    //直接往下标sz处添加,增加sz的值
    ps->data[ps->sz] = d;
    ps->sz++;
}

void PopBack(pSeqList ps)//尾删
{
    //断言
    assert(ps);

    //空
    if( 0 == ps->sz )
        return;

    //sz减一
    ps->sz--;
}
void Display(const pSeqList ps)
{
    int i;
    //断言
    assert(ps);

    //空
    if(  0 == ps->sz )
    {
        printf("顺序表为空\n");
        return;
    }

    //非空
    for( i=0; i<ps->sz; i++)
        printf("  %d",ps->data[i]);
    printf("\n");
}
void PushFront(pSeqList ps, DataType d)
{

    int i;

    //断言
    assert(ps);
    assert(ps->sz<MAX);

    //从后往前将每个元素往后挪动一格,然后给下标0处赋值,增加sz的值
    for( i=ps->sz; i>0; i--)
    {
        ps->data[i] =ps->data[i-1];
    }
    ps->data[0] = d;
    ps->sz++;
}

void PopFront(pSeqList ps)//头删
{
    int i;
    //断言
    assert(ps);

    //空
    if( 0 == ps->sz )
        return;

    //非空
    //从前往后将每个元素往前挪动一个,减小sz的值
    for( i=0; i<ps->sz-1; i++)
        ps->data[i] = ps->data[i+1];
    ps->sz--;
}

int Find(pSeqList ps, DataType d)
{
    int i;
    //断言
    assert(ps);

    //便利整个顺序表,找到该数据返回下标,遍历完未找到返回-1
    for( i=0; i<ps->sz; i++)
    {
        if( ps->data[i] == d)
            return i;
    }
    return -1;
}

void Insert(pSeqList ps, DataType d, int pos)//指定位置插入 
{
    int i;
    //断言
    assert(ps);

    //检测pos是否合法
    if( pos<0 || pos>ps->sz-1)
        return;

    //判满
    assert(ps->sz<MAX);

    //将pos及以后所有元素从后往前全部往后挪动一格,给pos处赋值,增加sz的值
    for( i=ps->sz; i>pos; i--)
        ps->data[i] = ps->data[i-1];
    ps->data[pos] = d;
    ps->sz++;
}
void del(pSeqList ps,int pos)//删除指定位置数据
{
    //由调用此函数的函数确定ps与pos是否合法,所以这里无需检测
    //将pos以后所有元素从前往后依次挪动一格,sz减一
    int i;
    for( i=pos; i<ps->sz-1; i++)
        ps->data[i] = ps->data[i+1];
    ps->sz--;
}
void Remove(pSeqList ps, DataType d)//删除首次出现的指定数据
{
    int i;
    //断言
    assert(ps);

    //遍历顺序表,找到指定数据删除,遍历终止
    for( i=0; i<ps->sz; i++)
    {
        if(ps->data[i] == d)
        {
            del(ps,i);//删除该元素
            return;
        }
    }
}
void RemoveAll(pSeqList ps, DataType d) //删除顺序表中所有指定数据
{
    int i;
    //断言
    assert(ps);

    //遍历顺序表,找到该数据并删除,遍历不终止
    for( i=0; i<ps->sz; i++)
    {
        if(ps->data[i] == d) 
        {
            del(ps,i);//删除该元素
            i--;
//因为调用del函数时,i下标处元素被删掉,后面所有元素往前挪动了一格此时ps->data[i]存储的是原来i+1下标处元素,如果没有i--,for循环调整部分i++会使得此元素没有被遍历到,且顺序表的元素减小了1位,但此循环仍然遍历到原来的最后一个元素处,会造成越界访问
        }
    }
}
void Reverse(pSeqList ps)//逆置顺序表 
{
    int i,j;
    //断言
    assert(ps);

    //空或者只有一个元素,直接返回
    if(ps->sz<=1)
        return;

    //设置两个下标,一个指向头,一个指向尾,同时往中间移动,交换两下标对应的元素
    for( (i=0,j=ps->sz-1); i<j; (i++,j--) )
    {
        DataType tmp = ps->data[i];
        ps->data[i] = ps->data[j];
        ps->data[j] = tmp;
    }
}
int cmp(void* a, void* b)
{
    return *(DataType*)a-*(DataType*)b;
}
void Sort(pSeqList ps) //排序
{
    //断言
    assert(ps);

    //空或只有一个元素
    if(ps->sz<=1)
        return;

    //多个元素
    qsort(ps,ps->sz,sizeof(DataType),cmp);
}
int BinarySearch(pSeqList ps, DataType d)//二分查找
{
    int left=0,right=ps->sz-1,mid;
    //断言
    assert(ps);

    //设置三个下标left,right,mid;若要找的元素小于mid,则将查找范围缩小到left到mid之间
    //否则缩小到mid到right之间,重复此步骤,直至找到或left>right
    while(left<=right)
    {
        mid = left+( (right-left)>>1);
        if( d == ps->data[mid])
            return mid;
        if( d < ps->data[mid])
            right = mid-1;
        else
            left = mid+1;
    }

    return -1;//未找到返回-1
}

测试代码test.c

#include "seqlist.h"

int main()
{
    int i;
    SeqList seq;
    pSeqList ps = &seq;
    InitSeqList(ps);
    //Display(ps);

    //PushBack(ps,1);
    //PushBack(ps,2);
    //Display(ps);

    //PopBack(ps);
    //Display(ps);

    //PushFront(ps,3);
    //PushFront(ps,4);
    //Display(ps);

    //PopFront(ps);
    //Display(ps);

    //i = Find(ps,1);
    //printf("%d\n",i);
    //if( -1!=i)
    //  Insert(ps,5,i);
    //Display(ps);

    //Remove(ps,1);
    //Display(ps);

    //PushBack(ps,5);
    //PushBack(ps,5);
    //Display(ps);

    ////RemoveAll(ps,5);
    ////Display(ps);

    //Reverse(ps);
    //Display(ps);

    //Sort(ps);
    //Display(ps);

    PushBack(ps,1);
    PushBack(ps,8);
    PushBack(ps,23);
    PushBack(ps,96);
    PushBack(ps,9);
    PushBack(ps,0);
    PushBack(ps,65);
    PushBack(ps,34);

    Sort(ps);
    Display(ps);

    i=BinarySearch(ps,0);
    i=BinarySearch(ps,1);
    i=BinarySearch(ps,2);
    i=BinarySearch(ps,3);
    i=BinarySearch(ps,4);
    i=BinarySearch(ps,5);
    i=BinarySearch(ps,6);
    i=BinarySearch(ps,7);
    i=BinarySearch(ps,8);
    i=BinarySearch(ps,9);
    i=BinarySearch(ps,10);
    i=BinarySearch(ps,-2);

    return 0;
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值