线性表的顺序存储

来源:互联网 发布:squid 3.5 windows 编辑:程序博客网 时间:2024/05/13 00:27

线性表的顺序存储

  • 线性表的顺序存储
    • 基本概念
    • 设计和实现
      • 1 插入元素算法
      • 2 获取元素操作
      • 3 删除元素算法
      • 4 具体代码
    • 优缺点

1.基本概念

这里写图片描述

2.设计和实现

2.1 插入元素算法

  • 判断线性表是否合法
  • 判断插入位置是否合法
  • 把最后一个元素到插入位置的元素后移一个位置
  • 将新元素插入
  • 线性表长度加1

2.2 获取元素操作

  • 判断线性表是否合法
  • 判断位置是否合法
  • 直接通过数组下标的方式获取元素

2.3 删除元素算法

  • 判断线性表是否合法
  • 判断删除位置是否合法
  • 将元素取出
  • 将删除位置后的元素分别向前移动一个位置
  • 线性表长度减1

2.4 具体代码:

  • 头文件:
#pragma#include <stdio.h>#include <stdlib.h>#include <memory.h>/*数据类型的封装--使用void类型*/typedef void SeqList;typedef void SeqListNode;//接受任意类型的数据元素,                        //存放的是具体数据元素的首地址,                        //不是直接存放数据元素/*顺序存储各个函数*/SeqList* SeqList_Create(int capacity);void SeqList_Destroy(SeqList* list);void SeqList_Clear(SeqList* list);int SeqList_Length(SeqList* list);int SeqList_Capacity(SeqList* list);int SeqList_Insert(SeqList* list, SeqListNode* node, int pos);SeqListNode* SeqList_Get(SeqList* list, int pos);SeqListNode* SeqList_Delete(SeqList* list, int pos);
  • 实现文件
#include "seqlist.h"/*表头数据结构*/typedef struct _MyStruct{    int length;//当前实际长度    int capacity;//容量    unsigned int * node;//线性表的起始位置,线性表里的每一个节点存放的是地址值,                        //该地址是每个数据元素的起始地址,类似于Linux内核里面的链表思想}TSeqList;/*创建线性表*/SeqList* SeqList_Create(int capacity){    TSeqList * tmp = NULL;//表头    tmp = (TSeqList*)malloc(sizeof(TSeqList));//为表头分配内存    if (NULL == tmp)    {        printf("Sorry!\n");        return NULL;    }    memset(tmp, 0, sizeof(TSeqList));//初始化表头    /*根据容量分配内存*/    tmp->node = (unsigned int *)malloc(sizeof(unsigned int )*capacity);    if (tmp->node == NULL)    {        printf("sorry!!\n");        return NULL;    }    /*初始化容量和长度*/    tmp->capacity = capacity;    tmp->length = 0;    /*返回表头*/    return tmp;}/*销毁线性表*/void SeqList_Destroy(SeqList* list){    TSeqList * tmp = NULL;    /*合法性检测*/    if (list == NULL)    {        return ;    }    tmp = (TSeqList*)list;    /*先释放线性表*/    if (tmp->node != NULL)    {        free(tmp->node);    }    /*再释放表头*/    free(tmp);    return ;}/*清空线性表*/void SeqList_Clear(SeqList* list){    TSeqList * tmp = NULL;    if (list == NULL)    {        return ;    }    tmp = (TSeqList*)list;    tmp->length = 0;//清空长度即可    return ;}/*获取线性表长度*/int SeqList_Length(SeqList* list){    TSeqList * tmp = NULL;    if (list == NULL)    {        return -1;    }    tmp = (TSeqList*)list;    return tmp->length;}/*获取容量*/int SeqList_Capacity(SeqList* list){    TSeqList * tmp = NULL;    if (list == NULL)    {        return -1;    }    tmp = (TSeqList*)list;    return tmp->capacity;}/*插入元素:把数据元素的首地址放进线性表的节点*/int SeqList_Insert(SeqList* list, SeqListNode* node, int pos){    TSeqList * tmp = NULL;    int i = 0;    /*合法性判断*/    if (list == NULL || node == NULL || pos < 0)    {        printf("argv is error\n");        return -1;    }    tmp = (TSeqList*)list;    /*线性表是否已满*/    if (tmp->capacity <= tmp->length)    {        printf("is full\n");        return -2;    }    /*给出的目标位置是否合理*/    if (pos >= tmp->length)    {        pos = tmp->length;//容错纠正    }    /*元素后移*/    for (i = tmp->length; i > pos;i--)    {        tmp->node[i] = tmp->node[i - 1];    }    tmp->node[i] = (unsigned int)node;//将数据元素首地址直接存入线性表节点中    tmp->length++;//长度修改    return 1;}/*获取指定位置的元素*/SeqListNode* SeqList_Get(SeqList* list, int pos){    TSeqList * tmp = NULL;    if (list == NULL || pos < 0)    {        printf("argv is error\n");        return NULL;    }    tmp = (TSeqList*)list;    return (void *)(tmp->node[pos]);//返回数据元素的首地址}/*从线性表删除指定位置的数据元素*/SeqListNode* SeqList_Delete(SeqList* list, int pos){    TSeqList * tmp = NULL;    SeqListNode * ret = NULL;    int i = 0;    if (list == NULL || pos < 0)    {        printf("argv is error\n");        return NULL;    }    tmp = (TSeqList*)list;    /*容错纠正*/    if (pos >= tmp->length)    {        pos = tmp->length;    }    /*获取要删除的数据元素的首地址*/    ret = (void*)(tmp->node[pos]);    /*元素前移*/    for (i = pos + 1; i < tmp->length; i++)    {        tmp->node[i - 1] = tmp->node[i];    }    tmp->length--;//修改长度    return ret;//返回被删除的数据元素首地址} 
  • 测试文件
#include "seqlist.h"typedef struct _Teacher{    int age;    char name[64];}Teacher;void main(){    int     ret = 0, i = 0;    SeqList* list = NULL;    Teacher t1, t2, t3, t4, t5;    t1.age = 31;    t2.age = 32;    t3.age = 33;    t4.age = 34;    t5.age = 35;    list = SeqList_Create(10);    if (list == NULL)    {        printf("func SeqList_Create() ret :%d \n", ret);        return;    }    ret = SeqList_Insert(list, (SeqListNode*)&t1, 0); //头插法    ret = SeqList_Insert(list, (SeqListNode*)&t2, 0); //头插法    ret = SeqList_Insert(list, (SeqListNode*)&t3, 0); //头插法    ret = SeqList_Insert(list, (SeqListNode*)&t4, 0); //头插法    ret = SeqList_Insert(list, (SeqListNode*)&t5, 0); //头插法    //遍历    for (i = 0; i<SeqList_Length(list); i++)    {        Teacher*  tmp = (Teacher *)SeqList_Get(list, i);        if (tmp == NULL)        {            return;        }        printf("tmp->age:%d ", tmp->age);    }    int var = 190;//同时插入Teacher和int类型的数据    ret = SeqList_Insert(list, (SeqListNode*)&var, 0); //再次证明该顺序表可以插入任意类型的数据元素    printf("%d\n%d\n",(*(int *)SeqList_Get(list, 0)) + 1,SeqList_Length(list));    //删除链表中的节点    while (SeqList_Length(list) > 0)    {        SeqList_Delete(list, 0);    }    SeqList_Destroy(list);    system("pause");    return;}

3. 优缺点

优点:

  • 无需为线性表中的逻辑关系增加额外的空间
  • 可以快速的获取表中合法位置的元素

缺点:

  • 插入和删除操作需要移动大量元素
  • 当线性表长度变化较大时难以确定存储空间的容量
0 0
原创粉丝点击