线性表顺序结构基本操作

typedef struct

{

int *list;

int length;//数据存储个数

int size;//申请的内存单元个数

}MYLIST;

已知线性表:MYLIST *myList;

1、初始化线性表      //实质就是对list指针进行初始化,此处我们选择动态初始化

initList(MYLIST* &temp)
{
    temp->list = (List*)malloc(sizeof(List)*10);
    if(!temp)
        exit -1;
    temp->length = 0;
    temp->size = 10;

}

//思考:函数内使用静态初始化是否可行?

如下图所示,函数内的数组为局部变量,实参取到的值为随机值,并不是函数内的实际值。

 上述问题解决办法:

在局部变量aa前添加static,延长aa的生命周期,此时取出的就是函数内局部变量的值了。

 

小结:可以发现动态存储和静态存储的区别:动态存储可以realloc进行增加内存,但是静态存储就没有办法了,所以还是选择动态存储。

2、销毁线性表//实质就是对释放list所指向的内存空间,针对动态申请的内存

destroyList(MYLIST* &temp)
{
    free(temp.list);
    temp->list = NULL;
    temp->length = 0;
    temp->size = 0;
}

3、线性表置空

clearList(MYLIST *&temp)
{
    temp->length = 0;//意为,其中的数据可以随意覆盖。
}

4、线性表是否为空

bool isEmptyList(MYLIST* temp)
{
    if(temp->length==0)//数据长度为0,就认为线性表为空。
        return true;
     else
        return false;
}

5、线性表数据长度

int lengthList(MYLIST* temp)
{
    return temp->length;
}

6、获取线性表中第n个元素

getElemList(MYLIST* temp,int n, int &value)
{
    if(n>temp->length||n<1)
        return ERROR;
    else
        {
           value = temp->list[n-1];//->与[]同运算级,结合性从左至右
            reuturn OK;
        }
}

 7、在线性表的第n个位置插入元素// n的范围是1--length+1,因为可以在最后一个元素的后面新增一个元素

insertElemList(MYLIST* &temp,int n,int value)
{
    if(n<1||n>temp->length+1)
        return ERROR;
    if(temp->length==temp->size)//空间已满
    {
        int*add = (int*)realloc(temp->list,(temp->size+1)*sizeof(int));
        if(!add)
         exit -1;
        for(int i=temp->length-1; i>=n-1;i--)//转化为数组的下标,最后一个下标和第n个下标
        {
           temp->list[i+1]= temp->list[i];
        }
        temp->list[i+1]= value;
    }else                    //空间没满
    {

        for(int i=temp->length-1; i>=n-1;i--)//转化为数组的下标,最后一个下标和第n个下标
        {
           temp->list[i+1]= temp->list[i];
        }
        temp->list[i+1]= value;
    }
    temp->length++;
    temp->size++;
}

以上程序,发现空间满与不满,代码有重复的地方,故可以合并如下:

insertElemList(MYLIST* &temp,int n,int value)
{
    if(n<1||n>temp->length+1)
        return ERROR;
    if(temp->length==temp->size)//空间已满
    {
        int*add = (int*)realloc(temp->list,(temp->size+1)*sizeof(int));
        if(!add)
         exit -1;
       temp->list = add;
    }                  
    
     for(int i=temp->length-1; i>=n-1;i--)//转化为数组的下标,最后一个下标和第n个下标
     {
        temp->list[i+1]= temp->list[i];
     }
     temp->list[i+1]= value;
    
    temp->length++;
    temp->size++;
}

 以上代码可以这么理解:空间满,申请一个空间,那么空间就不满了,就与空间不满代码一致了。

8、线性表中删除第n个元素

deleteElemList(MYLIST * &temp,int n,int &elem)
{
    if(n>temp->length||n<1)
        return ERROR;
    int* p = temp->list+n-1;
    elem = *p;
    int* q = temp->list+temp->length-1;//q指向线性表中最后一个元素
    for(; p<=q-1;p++)
    {
        *p = *(p+1);
    }
    temp->length--;
}

9、线性表中取某元素的直接前驱

bool priorElemList(MYLIST temp, int value ,int &ret)
{
    int *p = temp->list;        
    for(;p<=temp->list+length-1;p++)
    {
         if(*P==value)
            {
                if(p !=temp->list)   //除了第一个元素外,都有直接前驱
                     {
                        ret = *(p-1);  
                        return true;
                      }                     
            }            
    }
    return false;
}

 分析:上述例子是一个常规的,正向的分析思路,即,在遍历线性表中的元素,找到符合条件的那个值。

那么,也可以进行反向的分析,即,遍历线性表中元素,剔除掉不符合条件的值,剩下的那个就是符合条件的值。

bool priorElemList(MYLIST temp, int value ,int &ret)
{
    int *p = temp->list;        
    for(;p<=temp->list+length-1;p++)
    {
         if(*P!=value)
            continue;
         else
            break;            
    }
    if(p !=temp->list&&p!=temp->list+length)//跳出循环2种情况:一种是break一种是for循环结束;
    {
         ret = *(p-1);                      // 或者没有进入循环
         return true;
    }           
    return false;
}

 上文中的for循环又可以改写成以下:因为,for循环(while循环)本来就是满足循环条件执行循环体,不满足跳出循环,且循环其实就是多个if的表达-----不满足条件执行{}外的语句。

for(;p<=temp->list+length-1;p++)
{
    if(*P!=value)
        continue;
    else
        break;            
}


//上例又可以改写成如下:
for(;p<=temp->list+length-1&&*P!=value;p++) ;//不满足循环条件,退出
if(p<=temp->list+length-1)              
{
    ret = *(p-1);                     
    return true;
}
return false;

//故退出for循环后,p>temp->list+length-1  或者 *p==value;
//此时只需排除上述两者可能的一种,就一定是另一种可能。
//理解:有件事,是A或者B做的,已知不是A,那么肯定就是B了。

//另外,上例又可以改写成while循环示例:
while(p<=temp->list+length-1&&*P!=value) p++;

 10、线性表中取某元素的直接后继

nextElemList(MYLIST temp,int value, int &ret)
{
    int *p = temp->list;
    for(;p<temp->list+temp->length-1&&*p!=value;p++)
    {            
    }
    if(p<temp->list+temp->length-1)
    {
        ret = *(p+1);                     
        return true;
    }  
    return false;
}

11、线性表中查找与值满足某函数关系的第n个元素

int findElemList(MYLIST* temp,int value,bool(*myfunc)(int,int))
{
    int *p = temp->list;
    int n = 1;
    for(;p<temp->list+temp->length && !myfunc(value,*p);p++,n++)
    {
          
    }
    if(p<temp->list+temp->length)
    {
        return n;
    }
    return 0;
} 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值