数据结构基础之顺序表

1.顺序表(链式存储)

顺序表的基本操作:

//可扩容的链式存储顺序表结构体设计
typedef int ELEM_TYPE;
#define INIT_SIZE 10  //初始化时malloc的开辟空间大小
typedef struct SeqList
{
	ELEM_TYPE* elem; //接收malloc返回的数组首地址
	int length;   //存放有效值个数
	int listsize;	//存放数组的总大小
}SeqList, * PSeqList;

1.初始化

void Init_SeqList(struct SeqList* head)
{
    //0.安全性处理
    //若传入的head指针为NULL,后续对head->data或其他行为的访问会导致程序崩溃
    assert(NULL != head) ;
    if(NULL == head) exit(EXIT_FAILURE);
    
    //1.对elem来malloc,再堆区malloc连续空间
    head->elem = (ELEM_TYPE*)malloc(INIT_SIZE*sizeof(ELEM_TYPE));
    //判断malloc是否成功
    if(NULL == head->elem) exit(EXIT_FAILURE);
    
    //2.对length和listsize初始化
    head->length = 0 ;
    head->listsize = INIT_SIZE ;
    
}

2.插入数据

//头插法
bool Insert_SeqList_head(PSeqList head,ELEM_TYPE val)
{
    //0.安全性处理
    assert(NULL != head) ;
    if(NULL == head) exit(EXIT_FAILURE);
    
    //0.判满 若满则扩容
    if(Is_Full(head)) Increase(head);
    
    //1.集体向后移动
    for(int i = head->length - 1;i >= 0 ;i++)
    {
        //由第i位置的元素覆盖第i+1位置的元素
        head->elem[i+1] = head->elem[i];
    }
    //2.插入0号下标
    head->elem[0] = val;
    head->length++;//长度加一
    return true;
}

//尾插法
bool Insert_SeqList_tail(PSeqList head,ELEM_TYPE val)
{
    //0.安全性处理
    assert(NULL != head);
    if(NULL == head) exit(EXIT_FAILURE);
    //1.判满 若满则扩容
    if(Is_Full(head)) Increase(head) ;
    //1.插入元素 尾插不需要挪动元素
    //length指向的位置是下一次要插入的位置,所以不需要-1
    head->elem[head->length] = val;
    head->length++;
    return true;
}

//按位置插入
bool Insert_SeqList_pos(PSeqList head,ELEM_TYPE val,int pos)
{
    //0.安全性处理
    assert(NULL != NULL);
    //判断pos位置的合法性,避免pos指向非法位置
    assert(pos >= 0 && pos <=head->length);
    if(NULL == head) exit(EXIT_FAILURE);
    //1.判满
    if(Is_Full(head)) Increase(head) ;
    //2.将插入位置之后的元素同意向后挪动,空出待插入位置
    //当i==pos时的元素也要挪动,因为val要插在pos位置
    for(int i = head->length - 1;i >= pos ; i++)
    {
        head->elem[i+1] = head->elem[i];
    }
    //3.插入元素,length++
    head->elem[pos] = val;
    head->length++;
    return true;
}

3.删除数据

在线性表中,删除元素即是覆盖元素

//头删
bool Del_SeqList_head(SeqList* head)
{
    //0.安全性处理
    assert(NULL != head);
    if(NULL == head) exit(EXIT_FAILURE);
    //1.判空
    if(Is_Empty(head)) return false;
    //2.头删 即将第一个位置的元素覆盖
    for(int i = 1;i < head->length ; i++)
    {
        head->elem[i-1] = head->elem[i];
    }
    head->length--;
    return true;
}

//尾删
bool Del_SeqList_head(SeqList* head)
{
    //0.安全性处理
    assert(NULL != head);
    if(NULL == head) exit(EXIT_FAILURE);
    //1.判空
    if(Is_Empty(head)) return false;
    head->length--;//此时length指向的位置即便有值,也是无效值,下次插入即覆盖
    return true;
}

//按位置删
bool Del_SeqList_pos(SeqList* h, int pos)
{
    //0.安全性处理
    assert(NULL != head);
    if(NULL == head) exit(EXIT_FAILURE);
    //1.判空
    if(Is_Empty(head)) return false;
    //2.找到要删除元素的位置,然后将其之后的元素全部向前挪动,即覆盖掉了要删除的元素
    for(itn i = pos + 1;i < head->length ; i++)
    {
        head->elem[i+1] = head->elem[i];
	}
    head->length--;
    return true;
}

//按值删(只删除该值第一次出现的位置)
bool Del_SeqList_val(SeqList* head, ELEM_TYPE val)
{
    //0.安全性处理
    assert(NULL != head);
    if(NULL == head) exit(EXIT_FAILURE);
    //1.判空
    if(Is_Empty(head)) return false;
    //2.通过调用查找函数,查找val在顺序表的位置
    int index = Search_SeqList(head, val);
    if(index == -1) return false;//没找到值,该值不存在
    else Del_SeqList_pos(head,index);//有了位置后,就可以调用按位置删函数
    return true;
}

//按位置删(删除所有val值)
bool Del_SeqList_AllVal(SeqList* head, ELEM_TYPE val)
{
    //0.安全性处理
    assert(NULL != head);
    //1.判空
    if(Is_Empty(head)) return false;
    //双指针法
    int slow = 0;
    for(int fast = 0 ; fast < head->length ; fast++)
    {
        if(head->elem[fast] != val)
        {
            //保留非目标val值
            head->elem[slow++] = head->elem[fast];
        }
    }
    //此时slow值即length新的长度
    head->length = slow;
    return true;
    
}

4.查找数据

//4.查找数据是否已经存在(存在则返回下标,反之返回-1)
int Search_SeqList(PSeqList head, ELEM_TYPE val)
{
	for (int i = 0; i < head->length; i++)
	{
		if (head->elem[i] == val) return i;
	}
	return -1;
}

5.判空与判满

//判空
bool Is_Empty(PSeqList head)
{
	return head->length == 0;
}

//判满
bool Is_Full(PSeqList head)
{
	return head->length == head->length;
}

6.扩容函数

//扩容函数 默认两倍扩容
void Increase(PSeqList psl)
{
	ELEM_TYPE* tmp = (ELEM_TYPE*)realloc(psl->elem, psl->listsize * sizeof(ELEM_TYPE) * 2);
	//扩容是否成功
	if (tmp != nullptr)
	{
		psl->elem = tmp;
	}
}

7.清空与销毁

//清空   无需释放malloc购买的内存
void Clear(PSeqList head)
{
	head->length = 0;
}

//销毁   需释放malloc购买的内存
void Destory(PSeqList head)
{
	free(head->elem);
	head->length = head->listsize = 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值