线性表的初级认识

简介: 线性表的初级认识

一,线性表的定义

       线性表是最为基础的逻辑结构,是n个相同属性元素的有限序列,而数据元素在线性表中的位置取决于它自身的序号,它所对应的逻辑结构如图:

              通常我们需要设置一系列连续的数据时使用线性表。

二,线性表的基本运算

       线性表的运算方式复杂多样,种类也繁多,但对于初学者来说,线性表的常用运算我进行了一下总结:

(1)设置基础的线性表

(2)增添线性表中的数据元素

(3)展示线性表中的数据元素

(4)删除线性表中的数据元素

(5)查找线性表中的数据元素

(6)修改线性表中的数据元素

       线性表虽然有不同的种类,但对于初学者的基本操作都基本归于以上几种类型

三,线性表中的顺序表

       首先,我们先来介绍一下线性表中的顺序表。顺序表是用来存储线性表最简单,最常用的方式,是在计算机中开辟一系列连续的内存空间进行存储不同的数据元素。顺序表具有物理相邻的特点。我们之前设置的基础通讯录就运用的是顺序表。下面,我以C++中的通讯录设置的算法来跟大家演示一下顺序表中的基本运算:

(1)设置基础的线性表,在这里我以结构体的形式设置,也可用数组的形式,但设置起来比较麻烦,思路基本相同。

//首先,设置通用的数据元素,即线性表的数据元素

struct person

{

   string name;

   int sex;

   int age;

   string phone;

   string number;

   string address;

};

//然后,用数组的形式将一系列数据元素构成线性表

struct add

{

   struct person arr[m];

   int size;

}a;

(2)增添线性表中的数据元素,要考虑线性表是否满载的情况,具体方法如下

void addperson(struct add* a,int* p)//基础运算中的增添算法

{

   if (a->size == m)//当线性表满了时候的情况

   {

       cout << "通讯录存放已满,无法添加" << endl;

       return;

   }

   else//当线性表没有存储满时进行增加数据元素

   {

       //姓名

       cin >> a->arr[*p].name;

       //性别

       cout << "1,男\n" << "2,女" << endl;

       while (true)

       {

           int select;

           cin >> select;

           if (select == 1 || select == 2)

           {

               if (select == 1)

                   a->arr[*p].sex = 1;

               else

                   a->arr[*p].sex = 2;

               break;

           }

       }

      //年龄

       cin >> a->arr[*p].age;

      //电话

       cin >> a->arr[*p].phone;

       //身份证号

       cin >> a->arr[*p].number;

       //地址

       cin >> a->arr[*p].address;

   }

}

(3)展示线性表中的数据元素,线性表具有物理相邻的特点,我们可用这一性质来查看线性表中的所有数据元素或数据项

void show(struct add* a)
{
   if (a->size == 0)
//当线性表没有任何数据元素时的情况

       cout << "当前没有任何记录" << endl;
   else
//当有元素时进行输出

   {
       for (int i = 0; i < a->size; i++)
//直接从物理上的开始位置起查找

       {
           cout << "姓名: " << a->arr[i].name << "   ";
           cout << "性别: " << (a->arr[i].sex == 1 ? "男" : "女") << "   ";
           cout << "年龄: " << a->arr[i].age << "   ";
           cout << "手机号: " << a->arr[i].phone << "   ";
           cout << "身份证号: " << a->arr[i].number << "   ";
           cout << "家庭地址: " << a->arr[i].address << endl;
       }
   }
}

(4)删除线性表中的数据元素,在这里我们要删除指定的数据项,将其对应的数据元素一起删除

可以先设置一个算法,先查找要删除的位置,然后进行删除

int foundperson(add* a,string name1)//查找指定人的位置

{
   for (int i = 0; i < a->size; i++)
   {
       if (a->arr[i].name == name1)
       {
           return i;
       }
   }
   return -1;
}
void deleteperson(add* a)
//要删除指定的人的姓名

{
   string name;
   int number;
   cin >> name;
   number = foundperson(a, name);
   if (number != -1)
   {
       for (int i = number; i < a->size; i++)
       {
           a->arr[i] = a->arr[i + 1];
       }
       a->size--;
       cout << "删除成功" << endl;
   }
   else
//当没有要删除指定的这个人时的情况

   {
       cout << "没有此人" << endl;
   }
}

(5)查找线性表中的数据元素,跟删除操作基本一致,先查找指定人的具体位置,然后根据这个线性表对应的物理位置直接查找

int foundperson(add* a,string name1)//查找指定人的位置,name1对应的是查找人的名字

{
   for (int i = 0; i < a->size; i++)
   {
       if (a->arr[i].name == name1)
       {
           return i;
       }
   }
   return -1;
}

void found(add* a)
{
   int i;
   string name;
   cin >> name;
   i = foundperson(a, name);
//指定查找人的位置

   if (i != -1)//查找人的基本信息

   {
       cout << "姓名: " << a->arr[i].name << "   ";
       cout << "性别: " << (a->arr[i].sex == 1 ? "男" : "女") << "   ";
       cout << "年龄: " << a->arr[i].age << "   ";
       cout << "手机号: " << a->arr[i].phone << "   ";
       cout << "身份证号: " << a->arr[i].number << "   ";
       cout << "家庭地址: " << a->arr[i].address << endl;
   }
   else
//当没有查到的情况

   {
       cout << "没有此人" << endl;
   }
}

(6)修改线性表中的数据元素,先找到数据项的位置,然后根据物理位置进行修改

int foundperson(add* a,string name1)//指定人的位置算法

{

   for (int i = 0; i < a->size; i++)

   {

       if (a->arr[i].name == name1)

       {

           return i;

       }

   }

   return -1;

}

void fix(add* a)

{

   int number;

   string name;

   cin >> name;

   number = foundperson(a, name);//指定人的位置

   if (number != -1)//进行修改

   {

          //姓名

           cin >> a->arr[*p].name;

           //性别

           while (true)

           {

               int select;

               cin >> select;

               if (select == 1 || select == 2)

               {

                   if (select == 1)

                       a->arr[*p].sex = 1;

                   else

                       a->arr[*p].sex = 2;

                   break;

               }

           }

           //年龄

           cin >> a->arr[*p].age;

           //电话

           cin >> a->arr[*p].phone;

          //身份证号

           cin >> a->arr[*p].number;

          //地址

           cin >> a->arr[*p].address;

       }

   }

   else

   {

       cout << "没有此人" << endl;

   }

}

      由此可见,在基础操作中,查找,修改,删除三种方法基本思路一样,换种情其实也是一样的,你可以私下想象一下。

四,线性表中的链式表

      链式表其实就是我们之前学的链表。链表具有相连的逻辑关系,它可以表示各种复杂的非线性结构式。链表的逻辑结构要比顺序表的情况稍微复杂一点点。常见的链表形式有单向链表,双向链表,循环链表。

1,单向链表

      单向链表是最简单,最常用的链式结构之一,单链表中的每个结点只包含一个指针域,如图:

       下面为单向链表的创建与输出:

#include<stdio.h>

#include<stdlib.h>

typedef int type;

typedef struct h

{

   type a;

   struct h* next;

}Lnode;

Lnode* Link()

{

   type a, i = 0;

   Lnode* head = NULL, * p, * pa;

   head = p = (Lnode*)malloc(sizeof(Lnode));

   fscanf(stdin, "%d", &a);

   while (a != 0)

   {

       i++;

       if (i == 1)

       {

           head->a = a;//因为位顺序结构式,要先确定头节点

       }

       p->a = a;//当满足式子时加入,数据加入表中

       pa = (Lnode*)malloc(sizeof(Lnode));//建立结点

       p->next = pa;//建立连接

       p = pa;//顺序链接,建立相应的关系式子

       fscanf(stdin, "%d", &a);

   }

   p->next = NULL;

   return head;

}//以上已成功建立

type main()

{

   Lnode * t;

   for (t = Link(); t->next != NULL; t = t->next)

   {

       fprintf(stdout, "%d ", t->a);

   }

   return 0;

}

 

2,双向链表

       单项链表中的每个结点只能指向前面的结点,如果再加上一个指针域指向后面的结点,这种链表称为双向链表。如图:

下面为双向链表的创建与双向输出

#include"linkc.h"//自己写的必要头文件

struct pa

{

   type a;

   link* next1, * next2;//next1指向前趋,next2指向后继

};

int main()

{

   int n = 0;

   link* p, * pp, *head;

   p = head = (link*)malloc(sizeof(link));

   scanf("%d", &p->a);

   while (p->a)

   {

       pp=(link*)malloc(sizeof(link));

       scanf("%d", &pp->a);

       p->next1 = pp;

       pp->next2 = p;//逆向建立连接,建立双向

       p = pp;

   }

   p->next1 = 0;//正向的末尾

   head->next2 = 0;//逆向的末尾

   //双向链表正向输出

   for (pp = head; pp->next1; pp = pp->next1)

   {

       printf("%d ", pp->a);

       Sleep(500);

   }

   printf("\n");

  //双向链表的逆向输出

   for (pp = p; pp->next2; pp = pp->next2)

   {

       printf("%d ", pp->a);

       Sleep(500);

   }

   return 0;

}

 

3,循环链表

循环链表是一种首尾相接的链表,具有无限循环结构。在单链表中,如果最后一个结点的指针域直接指向头节点,这就变成了循环链表。循环链表的结构式如图所示:

下面是循环链表的创建和输出的代码演示:

#include"linkc.h"//头文件,里面我们设置的一些简单的基础操作

struct pa

{

   type a;

   link* next;

};

int main()

{

   link* p, * head, * pp;

   p = head = (link*)malloc(sizeof(link));

   scanf("%d", &p->a);

   while (p->a)//终止条件为0

   {

       pp = (link*)malloc(sizeof(link));

       scanf("%d", &pp->a);

       p->next = pp;

       p = pp;

   }

   p->next = head;//将最后结点指向头节点

   for (pp = head;; pp = pp->next)//查看循环链表,不用设置条件

   {

       printf("%d\n", pp->a);

       Sleep(500);//控制输出时间,因为循环链表是无限循环

   }

   return 0;

}

 

总:单向链表,双向链表,循环链表都是基础的链式结构,更为复杂的如双向循环链表,双向带头循环链表等,但需注意的是,虽然链式结构复杂多样,基本的运算规律都是一致的思想,只要在形式上稍微改动即可,初级的线性表一共大约也就这么多,顺序表比较简单,没有涉及复杂的结构和逻辑思想,至于跟为复杂的链式结构式以及线性表的使用逻辑和注意事项,后面的深入文章会给大家做出详细的讲解。

相关文章
|
7月前
|
存储
实现单链表的基本操作(力扣、牛客刷题的基础&笔试题常客)
实现单链表的基本操作(力扣、牛客刷题的基础&笔试题常客)
200 38
|
7月前
|
算法 Java
数据结构奇妙旅程之二叉树题型解法总结
数据结构奇妙旅程之二叉树题型解法总结
|
算法 搜索推荐
【八大排序(七)】归并排序初级篇-递归版
【八大排序(七)】归并排序初级篇-递归版
|
7月前
|
存储 算法 Java
【数据结构与算法】4.自主实现单链表的增删查改
【数据结构与算法】4.自主实现单链表的增删查改
【初级指针】
【初级指针】
52 0
|
存储 人工智能 Java
线性表入门
大家好,我是王有志。从今天开始就进入到数据结构的部分了,整体分为3个部分:线性表,树和图,从认识每种数据结构到它们的高级应用。今天我们先从最简单的的线性表和数组开始。
80 1
线性表入门
|
存储 C语言
初级指针详解
初级指针详解
112 0
数据结构练级之路【小白白的初级单链表题目】
数据结构练级之路【小白白的初级单链表题目】
|
存储 算法 C++
一篇文章带你彻底理解线性表,超详细千字总结对比!
线性表 本章将详细地介绍线性表,包含线性存储和链式存储,同时介绍了抽象数据类型(ADT),并且使用cpp代码结合理论进行讲解,最后也附上了一些线性表相关的经典题型以便读者能理解线性表的作用以及能运用线性表。 可以转载,但请声明源链接:文章源链接justin3go.com(有些latex公式某些平台不能渲染可查看这个网站)
156 0
|
存储 算法 Java
数据结构与算法(二):线性表
上一篇《数据结构与算法(一):概述》中介绍了数据结构的一些基本概念,并分别举例说明了算法的时间复杂度和空间复杂度的求解方法。这一篇主要介绍线性表。
86 0