数据结构——线性表之顺序表

Posted Hunter丶安

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构——线性表之顺序表相关的知识,希望对你有一定的参考价值。

顺序表顺序表是由一段连续的储存单元存储数据的一种简单的数据结构形式,其优点在于快速的查找存储单元的值,缺点在于

时间复杂度 :查找:O(1),插入和删除:O(n);

对于清华大学《数据结构》——做出自己的理解;(用实例来理解抽象的事物)

假设,一次期末的成绩考试完后,老师需要将同学们的成绩输入到学校的系统内部去,同时能够改写成绩,添加学生等操作。

ADT{

    数据对象      

typedef struct
{
	char Name[Len];//学生的名字
	int Grade;//成绩
}Student;

typedef struct//基本结构
{
	Student *elem;//存储单元地址
	int length;//当前长度
	int listsize;//预设长度
}Sqlist;

    基本操作:

      List_Init(Sqlist &L);//对链表初始化  

void List_Init(Sqlist &L)
{
    L.elem = (Student*)(malloc(LIST_SIZE * sizeof(Student)));//C语言的开辟空间的方式。
    if (List_Empty(L)) 
        return;
    else//初始化值
    {
        L.length = 0;
        L.listsize = LIST_SIZE;
    }
}
View Code

        List_Empty(L)//取决于你对空的解释。

bool List_Empty(Sqlist L)
{
    return L.elem == NULL;
}
View Code

        List_Add_Insert(Sqlist &L , int coordinate , int newponit)//对链表添加和加入//如果对插入的算法不了解可以参考——这里

void List_Add_Insert(Sqlist &L, int coordinate , Student newpoint)
{
    if (coordinate < 1 || coordinate > L.length + 1)//插入的位置是否合法
    {
        cout << "插入的位置超出范围" << endl;
        return;
    }
    if (L.length >= L.listsize)//如果开辟的空间已满,则添加新的空间
    {
        Student *newbase = (Student*)realloc(L.elem, (L.listsize + LIST_SIZE) * sizeof(Student));
        if (newbase == NULL)//每次开辟空间后一定要检查是否成功,因为开辟空间是从堆中找到比你需要空间略大的空间然后赋地址的,如果找不到比你需要空间大的,则会失败。
            return;
        L.elem = newbase;
        L.listsize += LIST_SIZE;
    }
    Student *q = &L.elem[coordinate - 1];
    for (Student *p = &L.elem[L.length - 1]; p >= q; p--)//先把位置移动一位,腾出插入点的位置。
        *(p + 1) = *p;
    strcpy(q->Name, newpoint.Name), q->Grade = newpoint.Grade;//改变值
    ++L.length;//当前值增长
}
View Code

       List_Change(Sqlist &L)//和List_Get(Sqlist)相差无几,后面我就不另加叙述了。

void List_Change(Sqlist &L, int coordinate, Student newpoint)
{
    L.elem[coordinate - 1].Grade = newpoint.Grade;
}
View Code

         List_Erase(Sqlist &L , int coordinate)//删除位于coordinate位置的值。

void List_Erase(Sqlist &L, int coordinate)
{
    if (coordinate < 1 || coordinate > L.length)//删除位置超出范围
    {
        cout << "插入的位置超出范围" << endl;
        return;
    }
    Student *p = &L.elem[coordinate - 1];
    Student *q = &L.elem[L.length - 1];
    for (++p; p <= q; p++)//将删除位置进行覆盖
        *(p - 1) = *p;
    --L.length;//当前长度减少
}
View Code

        List_Length(Sqlist L)//得到链表现有长度——由于过于简单和可以用L.length直接表示,所以感觉作用不到大。

int  List_Length(Sqlist L)
{
    return L.length;
}
View Code

        List_Clear(Sqlist &L)//将链表原有值清空.

void List_Clear(Sqlist &L)
{
    for (int i = 0; i < L.length; i++)
        L.elem[i].Grade = 0, strcpy(L.elem[i].Name, "0");
}
View Code

}

完整的代码:GitHub地址

单链表存储空间非连续且存在前驱和后继的地址链接型的一种结构体,其优点在于快速的插入和删除,缺点就在于查找的不简便性。

时间复杂度:查找O(1),删除O(n);

ADT

{

    数据对象:

typedef struct
{
    char Name[Len];
    char ID[Len*2];
    char Sex[Len];
    char Tele[Len*2];
    char Addr[Len*2];
}Lode;
View Code
typedef struct Node
{
	Lode Data;//自定义的结构体类型
	struct Node *next;
}*Link_List;

     基本操作:

      List_Creat(List_link L)//初始化。

void List_Creat(Link_List L)
{
    bool flag = true;
    Node * rear = L;
    while (flag)
    {
        cout << "put:";
        Node *p = (Node*)malloc(sizeof(Node));
        if (p == NULL)
            print_Error();
        else
            p->next = NULL;
        To_Scanf(p);
        rear->next = p;
        rear = p;
        cout << "Q:退出输入,任意键继续输入!" << endl;
        if (getch() == \'q\')
            flag = false;
    }
}
View Code

      List_Inerst(List_Link L)//插入元素

void List_Inerst(Link_List L)
{
    //To_Imformate_Insert();
    int i = 0;
    bool flag = true;
    while (flag)
    {
        cout << "输入插入位置:";
        cin >> i;
        Node *p = L;
        int j = 0;
        while (p && j < i - 1)
        {
            p = p->next;
            ++j;
        }
        if (!p || j > i - 1)
        {
            cout << "Error!——重新输入" << endl;
            continue;
        }
        Node *s = (Node*)malloc(sizeof(Node));
        if (s == NULL)
            print_Error();
        else
        {
            cout << "输入插入元素的信息:";
            To_Scanf(s);
            s->next = p->next;
            p->next = s;
        }
        cout << "插入成功!" << endl;
        cout << "Q:退出输入,任意键继续输入!" << endl;
        if (getch() == \'q\')
            flag = false;
    }
}
View Code

        List_Delet(List_Link L)//删除元素

 List_Delet()
void List_Delet(Link_List L)
{
    //To_Imformate_Delet();
    int i = 0;
    bool flag = true;
    while (flag)
    {
        cout << "删除位置:";
        cin >> i;
        int j = 0;
        Node *p = L;
        while (p && j < i - 1)
        {
            p = p->next;
            ++j;
        }
        if (!p || j > i - 1)
        {
            cout << "Error!——重新输入" << endl;
            continue;
        }
        Node *q = p->next;
        p->next = q->next;//得到前二个元素
        free(q);
        cout << "删除成功:" << endl;
        cout << "Q:退出,任意键继续删除!" << endl;
        if (getch() == \'q\')
            flag = false;
    }
}

}

以上是关于数据结构——线性表之顺序表的主要内容,如果未能解决你的问题,请参考以下文章

数据结构之线性表之顺序存储Java实现

线性链表之顺序表

数据结构——线性表之顺序存储结构

线性表之顺序存储结构(顺序表)

数据结构线性表之顺序表ArrayList

数据结构学习总结线性表之顺序表