顺序表的C语言实现

在现实应用中,有两种实现线性表数据元素存储功能的方法,分别是顺序存储结构和链式存储结构。顺序表操作是最简单的操作线性表的方法。下面的代码实现了顺序表的几种简单的操作。代码如下

//start from the very beginning,and to create greatness
//@author: Chuangwei Lin
//@E-mail:979951191@qq.com
//@brief: 一个顺序表的简单例子
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
#define LIST_INIT_SIZE 10//初始化的顺序表长度
#define LISTINCREMENT 10//每次新增的长度
#define ERROR     0
#define OK        1
#define OVERFLOW  -2
//顺序表容器
typedef struct{
   int *elem;//表指针
   int length;//表长度
   int listsize;//表容量
}SqList;
/******************************************************
函数名:InitList_Sq(SqList *L)
参数:顺序表指针
功能:初始化顺序表
*******************************************************/
int InitList_Sq(SqList *L) //括号中传递参数是是它的指针L,这样才能对它指向的元素改变。
{
  int i;
  L->elem=(int *)malloc(LIST_INIT_SIZE*sizeof(int));//开辟空间
  if(!L->elem) //出错
   {
      exit(OVERFLOW);
   }
  L->length =10;
  L->listsize = LIST_INIT_SIZE; //分配初始的空间
  for(i=0;i<L->length;i++)
  {
      L->elem[i]=i;//表初始化为1,2,3,4......
  }
  return OK;
}
/******************************************************
函数名:get_length(SqList *L)
参数:表指针
功能:获取表长
*******************************************************/
int get_length(SqList *L)
{
    return L->length;
}
/******************************************************
函数名:destroy(SqList *L)
参数:表指针
功能:销毁顺序表
*******************************************************/
int destroy(SqList *L)
{
    L->length=0;
    return OK;
}
/******************************************************
函数名:ListInsert_Sq(SqList *L,int i, int e)
参数:表指针,插入位置,插入元素
功能:在顺序表L中的第i个位置之前插入新的元素e 
*******************************************************/
int ListInsert_Sq(SqList *L,int i, int e)
{ 
    //i的合法值为1<=i<=ListLength_Sq(L)+1;
    int *newbase,*q,*p;
    if(i<1||i>L->length+1)//插入位置不合法
      {
        return ERROR;
      }
    if(L->length >= L->listsize)
    {// 当前的存储空间已满,增加分配
         newbase = ( int *)realloc(L->elem,( L->listsize +LISTINCREMENT)*sizeof(int));
         if(!newbase) 
         {
            exit(OVERFLOW) ; //存储空间分配失败
         }
         L->elem = newbase;//更新基址地址
         L->listsize+=LISTINCREMENT;//增加表容量  
   }
   q=&(L->elem[i-1]);//从q位置开始后面的元素都应该要后移
   for(p=&(L->elem[L->length-1]);p>=q;--p) //从最后一个元素开始后移才不会覆盖
     {
        *(p+1)=*p; //插入位置及之后的元素右移  
     }
   *q=e;//插入元素
   ++L->length;//更新表长度
   return OK;
}
/******************************************************
函数名:ListDelete_Sq(SqList *L, int i, int* e)
参数:表指针,位置,返回值
功能:在顺序线性表L中删除第i个元素,并用e返回其值 
*******************************************************/
int ListDelete_Sq(SqList *L, int i, int* e) 
{  
  // i的合法值为1≤i≤ListLength_Sq(L)。
  int *p, *q;
  if (i<1 || i>L->length)
  {
    return ERROR;  // i值不合法
  } 
  p = &(L->elem[i-1]);// p为被删除元素的位置
  *e = *p;// 被删除元素的值赋给e
  q = L->elem+L->length-1;// 表尾元素的位置
  for (++p; p<=q; ++p)//从p位置开始移动
  {
    *(p-1) = *p;// 被删除元素之后的元素左移
  }
  --L->length; // 表长减1
  return OK;
} 
/******************************************************
函数名:display_all(SqList *L)
参数:表指针
功能:列出所有表元素
*******************************************************/
int display_all(SqList *L)
{
    int i;
    for(i=0;i<L->length;i++)
    {
        printf("%d  ",L->elem[i]);//打印表元素
    }
    printf("\n");
    return OK;
}
/******************************************************
函数名:search_by_num(SqList *L,int i)
参数:表指针,查找序号
功能:按序号查找
*******************************************************/
int search_by_num(SqList *L,int i)
{
  if (i<1 || i>L->length)
  {
    return ERROR;  // i值不合法
  } 
  printf("你查找的是第%d个值,内容为%d\n",i,L->elem[i-1]);
}
/******************************************************
函数名:search_by_value(SqList *L,int value)
参数:表指针,查找的值
功能:按元素查找
*******************************************************/
int search_by_value(SqList *L,int value)
{
  int i,j=0;//j作为找到的标志
  for(i=0;i<L->length;i++)
  {
    if (L->elem[i] == value)
    {
      j = 1;
      printf("你要找的元素找到啦!%d在第%d个\n",value,i+1);
    }
  }
  if (j == 0)
  {
    printf("你要的元素找不到\n");
  }
  return 0;
}
/******************************************************
函数名:
参数:
功能:主函数
*******************************************************/
int main()
{
    SqList L;
    int get,e=0;
    int i,num;
    InitList_Sq(&L);//初始化顺序表
    do{
        printf("请输入你要进行的操作序号\n");
        printf("1.线性表置空\n");
        printf("2.求线性表长度\n");
        printf("3.数据元素的插入操作\n");
        printf("4.数据元素的删除操作\n");
        printf("5.显示线性表中的全部元素\n");
        printf("6.按序号查找\n");
        printf("7.按元素的值查找\n");
        printf("8.退出\n");
        scanf("%d",&get);
        switch(get)
        {
          case 1:
                destroy(&L);//将顺序表置空,只需要将其长度置零
                break;
          case 2:
                printf("该线性表的长度是%d\n",get_length(&L)); //求取线性表的长度
                break;
          case 3:
                //在指定的位置上插入指定的数据元素
                printf("请输入你要插入的元素的位置(即在第i个元素之前插入)以及插入元素\n");
                scanf("%d,%d",&i,&num);
                ListInsert_Sq(&L,i,num);
                printf("新的线性表是\n");
                display_all(&L);
                break;
          case 4:
              //删除指定位置的数据元素
                printf("请输入你要删除的元素的位置(即删除第i个元素)\n");
                scanf("%d",&i);
                ListDelete_Sq(&L,i,&e);//要传进去e的地址才能得到值
                printf("删除的元素为%d\n",e);
                printf("新的线性表是\n");
                display_all(&L);
                break;
          case 5:
              //显示线性表的所有元素
                display_all(&L);
                break;
          case 6:
              //按序号查找
              printf("输入您要查找元素的序号\n");
              scanf("%d",&i);
              search_by_num(&L,i);
              break;
          case 7:
              //按值查找
              printf("输入您要查找的元素的值\n");
              scanf("%d",&num);
              search_by_value(&L,num);
          case 8:
              //退出程序
                break;
          default:
              printf("选取范围为1到8,请重新输入\n");
              break;
        }
    }while(get!=8);
    return OK;
}


运行结果:
这里写图片描述

posted @ 2015-08-15 11:19  sigma0  阅读(114)  评论(0编辑  收藏  举报