线性表--顺序表的操作

 
#include <stdio.h>
#include <stdlib.h>
#define LIST_INIT_SIZE 100;
#define LISE_INCREMENT 10;

//定义一个枚举常量,默认no = 0, ok = 1
enum Status{no, ok};

typedef struct Sqlist
{
   //数组元素类型是整型
   int *elem;//指针指向线性表的基地址,即数组名,数组的第一个元素的地址。
   //实质上,用一个指向首地址的指针代表了数组
   int length;//顺序表的实际元素个数,当前长度
   int listsize;//顺序表当前预分配的存储空间,预定义大小
}Sqlist;

//顺序表的初始化操作,就是为顺序表分配一个预定义大小的数组空间,
//并将线性表的当前长度设为‘0’,意思是当前数组中有0个元素。
//已经为数组分配了一定的内存空间,只是里面没放东西而已。
//实质上,就是定义一个变长数组。
//&L是一个地址,实质上是一个结构体的首地址,也就是用指针指向结构体首地址代表一个顺序表
Status InitList_Sq(Sqlist &L)
{
    //给结构体中的基地址赋值,类似于给数组的首地址赋值
   //构造一个空的线性表,预分配100存储空间
   L.elem = (int *)malloc(LIST_INIT_SIZE * sizeof(int));
   if(!elem)//在一个指针前加"!"运算符,表示该指针值与NULL相等,即P==NULL,也就是指针为空,或指针不存在
   return no;
   //下面两行,定义了一个有0个元素,但是占有100个空间的空表(空数组)
   L.length = 0;
   L.listsize = LIST_INIT_SIZE;
   return ok;
}

//顺序表的插入操作,主要是第n至i(共n-i+1)个元素依次后移动一个位置
Status ListInsert_Sq(Sqlist &L, int i, int e)
{//在顺序线性表L中第i个位置之前插入新的元素e 
   //i的合法值为1<=i<=List_length + 1
   if(i < 1 || i > L.length+1)
   return no;
   //若当前存储空间已满,增加分配
   if(L.length > L.listsize)
   {
      //realloc函数用来修改原指针所指向的对象的长度。
      int *new = (int *)realloc(L.elem,
	  (LIST_INIT_SIZE + LISE_INCREMENT) * sizeof(int));
	  if(!new)//存储分配失败
	  return no;
	  L.elem = new;//新基址
	  L.listsize += LISE_INCREMENT;//增加存储容量
   }
   int *q;//q为插入位置
   q = &(L.elem[i-1]);
   for(p=&(L.elem[L.length-1]); p>=q; ++p)
   *(p+1) = *p;//插入位置及之后的元素右移动
   *q = e;//插入e
   ++L.length;//元素个数增1
   return ok;
}

#include <stdio.h> #include <stdlib.h> #define INIT_LIST_SIZE 100 #define LISTINCREMENT 10

enum Status {no, ok};

//定义一个顺序表的结构体 typedef struct {    int *a;//顺序表中的基地址,    int len;    int size; }Sqlist;

Status Init_SqList(Sqlist &L) {    L.a = (int *)malloc(INIT_LIST_SIZE * sizeof(int));    if(L.a == NULL)    return no;    L.len = 0;//有0个元素    L.size = INIT_LIST_SIZE;//顺序表预设的空间    return ok; }

Status Insert_Sqlist(Sqlist &L, int i, int e) {    if(i < 1 || i > L.len + 1)    return no;    if(L.len >= L.size)//当存储空间已满的时候,重新分配    {       int *new = (int *)realloc(Sqlist &L,    (INIT_LIST_SIZE + LISTINCREMENT) * sizeof(int));    if(!new)    return no;    L.a = new;    L.size += LISTINCREMENT;    }    int *loc, *p;//loc为插入位置,p为操作指针    loc = &(L.a[i-1]);    for(p = &(L.a[len - 1]); p >= loc; --p)    *(p+1) = *p;//移动元素的操作-    *loc = e;//插入e    ++L.len;//表长增1    return ok;   }

顺序表插入运算步骤总结: 1, 初始化一个空顺序表 2, 判断插入位置是否合法 3, 若表满,分配新的空间,已被移动元素后,能在表中腾出位置以供插入 4, 从表尾依次移动元素,在待插入位置腾出一个空位 5, 插入元素 6, 表长增1.

 

//在顺序表中删除第i个元素 Status Delete_Sqlist(Sqlist &L, int i, int &e) {    int *p;//待删除元素    int *q;//表尾元素    //判断删除位置是否合法    if(i < 1 || i > L.len)    return no;    p = &(L.a[i-1]);//待删除元素的位置,也可写成 L.a + i - 1    e = *p;    q = L.a + L.len - 1;//表尾元素的位置,也可写成 &(L.a[len - 1])    for(p; p <= q; ++p)    *(p-1) = *p;//移动元素的操作    --L.len;//表长也要变化    return ok; }

顺序表删除元素运算总结: 1, 判断删除位置是否合法 2, 将操作指针p指向待删除的元素的存储位置 3, 将待删除元素的值取出,复制给e 4, 确定表尾元素的存储位置。 5, 循环处理操作指针P,移动元素,将后一项赋值给前一项,删除待删元素 6, 表长减1

//顺序表合并 Status Merge_Sqlist(Sqlist La, Sqlist Lb, Sqlist &Lc) {   //已知顺序表La,Lb的元素按值非递减排列   //归并La和Lb得到新的顺序线性表Lc,Lc的元素也按值非递减排列   int *pa, int *pb, int *pc;   int *pa_Last, *pb_Last;   pa = La.a;//指向La首地址的指针pa   pb = Lb.a;//指向Lb首地址的指针pb   Lc.size = Lc.len = La.len + Lb.len;//Lc的长度应该是La与Lb之和   //指向Lc首地址的指针pc   pc = Lc.a = (int *)malloc(Lc.size * sizeof(int));//创建Lc的存储空间   if(!pc)   return no;   pa_Last = La.a + La.len - 1;//La最后一个元素的存储地址   pb_Last = Lb.a + Lb.len - 1;//Lb最后一个元素的存储地址   //La与Lb都没有取完的情况下   while(pa <= pa_Last && pb <= pb_Last)   {     if(*pa <= *pb)  *pc++ = *pa++;\\等价于:*pc = *pa; pa++; pc++;  else  *pc++ = *pb++;   }   //Lb已经取完,只取La元素的情况下   while(pa <= pa_Last)   *pc++ = *pa++;   //La已经取完,只取Lb元素的情况下   while(pb <= pb_Last)   *pc++ = *pb++;   return ok; }

两个有序顺序表合并的运算总结: 1,先设置两个操作指针pa,pb,分别指向已有顺序表La,Lb的首地址。 2,再定义两个指针pa_Last,pb_Last,分别指向已有顺序表La,Lb的表尾地址,    以便于判断pa,pb是否滑动到La,Lb表尾。 3,通过初始化pc指针的方式来定义Lc顺序表,预先给Lc开辟长度为La.len + Lb.len的空间。 4,La与Lb都没有取完的情况下,通过比较取得两个表中元素的较小者,放入Lc中。 5,Lb已经取完,只取La元素并将其放到Lc中。 6,La已经取完,只取Lb元素并将其放到Lc中。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值