【数据结构】线性表(一):顺序列表

  线性表(linear_list)是最常用且最简单的一种数据结构,简言之,一个线性表是n个数据元素的有序序列。

 

例如:(a1 , ... , ai-1 , ai , ai+1 , ... , an):ai-1 是 ai 的直接前驱,ai+1 是 ai 的直接后驱。

并且,当 i = 1,2,... ,n-1:ai 有且只有一个直接后驱。当 i = 2,3,... ,n:ai 有且只有一个直接前驱

  

例子:已知线性表LA,LB中的数据元素按值非递减有序排列,现将LA,LB按值非递减排列合并为LC。其伪代码为:

 1 void MergeList(List La, List Lb, List &Lc) {
 2         initList(Lc);  //初始化Lc
 3         i = j = 1;
 4         k = 0;
 5         La_len = ListLength(La);
 6         Lb_len = ListLength(Lb);
 7         while((i <= La_len) && (j <= Lb_len){//La与Lb均非空
 8             GetElem(La, i, ai);
 9             GetElem(Lb, j, bj);
10             if(ai <= bj) {ListInsert(Lc, ++k, ai); ++i; }
11             else{ListInsert(Lc, ++k, bi); ++j;}
12         }
13         while(i <= La_len){       //La中剩余值插入Lc
14             GetElem(La, i++, ai);
15             ListInsert(Lc, ++k, ai);
16         }
17         while(j <= Lb_len){       //Lb中剩余值插入Lc
18             GetElem(Lb, j++, bj);
19             ListInsert(Lc, ++k, bj);
20         }
21 }

  分析:GetElem 和 ListInsert 这两个操作的执行时间和表长无关,所以该算法的事件复杂度为O(ListLength(LA) + ListLength(LB))。

 

线性表的顺序表示和实现:顺序表示指的是用一组地址连续的存储单元依次存储线性表的数据元素。

所以可以用 LOC(ai) = LOC(a1) + (i-1) * l  来表示ai的地址(其中:l 表示每个元素所占存储单元)

优点:轻松实现随机存储。

顺序表的初始化、插入、删除、合并的伪代码如下:

 

 1 // -------------线性表的动态分配顺序存储结构--------------
 2 #define LIST_INIT_SIZE 100   //线性表存储空间的初始化分配量
 3 #define LISTINCREMENT 10     //线性表存储空间的分配增量
 4 typedef struct{
 5     ElemType *elem;     //存储空间基址
 6     int length;         //当前长度
 7     int listsize;       //当前分配的存储容量(以sizeof(ElemType)为单位)
 8 }SqList;
 9 
10 //-----------初始化顺序表--------------
11 Status InitList_Sq(SqList &L){
12     //构造一个空的线性表
13     L.elem = (ElemType *)malloc(LIST_INIT_SIZE * sizeof(ElemType));
14     if(! L.elem)  eixt(OVERFLOW);       //存储分配失败
15     L.length = 0;                       //空表长度为0
16     L.listsize = LIST_INIT_SIZE;        //初始存储容量
17     return OK;
18 }
19 
20 //------------顺序表的插入算法-------------时间复杂度为O(n)
21 Status ListInsert_Sq(SqList &L, int i, ElemType e) {
22     //在顺序线性表L中第i个位置之前插入新的元素e
23     //i的合法值为1<=i<=ListLength_Sq(L)+1
24     if((i<1) || (i>L.length+1))  return ERROR;        //i值不合法
25     if(L.length >= L.listsize){           //当前存储空间已满,增加分配
26         newbase = (ElemType *)realloc(L.elem, (L.listsize + LISTINCREMENT)*sizeof(ElemTpye));
27         if(!newbase) exit(OVERFLOW);        //存储分配失败
28         L.elem = newbase;               //新基址
29         L.listsize += LISTINCREMENT;        //增加存储容量
30     }
31     q = &(L.elem[i-1]);         //q为插入位置
32     for(p = &(L.elem[L.length-1]); p >= q; --p) 
33         *(p+1) = *p;            //插入位置及之后的元素右移
34         *q = e;             //插入e
35         ++L.length;         //表长增一
36         return OK;
37 }
38 
39 //-------------顺序表的删除操作--------------时间复杂度为O(n)
40 Status ListDelete_Sq(SqList &L, int i, ElemType &e){
41     //在顺序线性表L中删除第i个元素,并用e返回其值。
42     if((i<1) || (i>L.length)) return ERROR;     //i值不合法
43     p = &(L.elem[i-1]);             //p为被删除元素的位置
44     e = *p;         //被删除元素的值赋给e
45     q = L.elem + L.length-1;        //表尾元素的位置
46     for(++p; p <= q; ++p){
47         *(p-1) = *p;    //被删除元素之后的元素左移
48     }
49     --L.length;         //表长减1
50     return OK;
51 }
52 
53 //-----------查找制定元素的位序---------------事件复杂度为O(n)
54 int LocateElem_Sq(SqList L, ElemType e, Status (* compare)(ElemType, ElemType)){
55     //在顺序线性表L中查找第1个值与e满足compare()的元素的位序
56     //若找到,则返回其在L中的位序,否则返回0
57     i = 1;              //i的初值为第一个元素的位序
58     p = L.elem;         //p的初值为第一个元素的存储位置
59     while(i <= L.length && !(* compare)(*p++, e)) ++i;
60     if(i<L.length) return i;
61     else return 0;
62 }
63 
64 //------------对于顺序表的合并------------------时间复杂度为O(La.length + Lb.length)
65 void MergeList_Sq(SqList La, SqList Lb, SqList &Lc) {
66     pa = La.elem;
67     pb = Lb.elem;
68     Lc.listsize = Lc.length = La.length + Lb.length;
69     pc = Lc.elem = (ElemType *) malloc (Lc.listsize*sizeof(ElemType));
70     if(!Lc.elem) exit(OVERFLOW);        //存储分配失败
71     pa_last = La.elem + La.length -1;
72     pb_last = Lb.elem + Lb.length -1;
73     while(pa <= pa_last && pb <= pb_last){  //归并
74         if(*pa <= *pb) *pc++ = *pa++;
75         else *pc++ = *pb++;
76     }
77     while(pa <= pa_last) *pc++ = *pa++;
78     while(pb <= pb_last) *pc++ = *pa++;
79

 

  C语言代码实现:

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include <string.h>
  4 
  5 #define LIST_INIT_SIZE 100      //线性表存储空间初始分配量
  6 #define LISTINCREMENT 10        //线性表存储空间的分配增量
  7 
  8 typedef struct {
  9     int *elem;      //存储空间基址
 10     int length;     //当前长度
 11     int listsize;   //当前分配的存储空间容量(以sizeof(int)为单位
 12 }SqList;
 13 
 14 //初始化一个新表
 15 void InitList_Sq(SqList *L){
 16     //构造一个空的线性表L
 17     (*L).elem = (int *) malloc(LIST_INIT_SIZE*sizeof(int));
 18     if(!(*L).elem) exit(-1);     //存储分配失败
 19     (*L).length = 0;
 20     (*L).listsize = LIST_INIT_SIZE;
 21 }
 22 
 23 //向表中第i个位置出插入一个数e
 24 void ListInsert_Sq(SqList *L, int i, int e){
 25     if(i<1 || i>(*L).length+1) {
 26         printf("插入时i值不合法...\n");
 27         exit(-1);
 28     }
 29     if((*L).length > (*L).listsize) {     //当前存储空间已满,增加分配
 30         int *newbase = (int *)realloc((*L).elem, ((*L).length+LISTINCREMENT)*sizeof(int));
 31         if(!newbase) exit(-1);
 32         (*L).elem = newbase;
 33         (*L).listsize += LISTINCREMENT;
 34     }
 35     int *q = &(*L).elem[i-1];
 36     for(int *p=&(*L).elem[(*L).length -1];p>=q;--p){
 37         *(p+1) = *p;
 38     }
 39     *q = e;
 40     ++(*L).length;
 41 }
 42 
 43 //删除表中第i个位置的数并返回到e中
 44 void ListDelete_Sq(SqList *L, int i, int *e){
 45     if(i<1 || i>(*L).length){
 46         printf("删除时i值不合法...\n");
 47         exit(-1);
 48     }
 49     int *p = &(*L).elem[i-1];       //要删除的元素
 50     *e = *p;                        //被删除的元素赋值给e
 51     int *q = &(*L).elem[(*L).length-1];     //表尾元素
 52     for(++p;p<=q;p++){          //被删除元素之后的元素左移
 53         *(p-1) = *p;            
 54     }
 55     --(*L).length;
 56 }
 57 
 58 void MergeList_Sq(SqList La, SqList Lb, SqList *Lc){
 59     //已知顺序表La,Lb的元素按值非递减排列
 60     //归并La,Lb得到新的顺序列表Lc,Lc的元素也按值非递减排列
 61     int *pa = La.elem;
 62     int *pb = Lb.elem;
 63     (*Lc).listsize = (*Lc).length = La.length + Lb.length;
 64     int *pc = (*Lc).elem = (int *)malloc((*Lc).listsize * sizeof(int));
 65     if(!(*Lc).elem){
 66         printf("内存分配失败...\n");
 67         exit(-1);
 68     }
 69     int *pa_last = La.elem + La.length -1;      //La的表尾元素地址
 70     int *pb_last = Lb.elem + Lb.length -1;      //Lb的表尾元素地址
 71     while(pa<=pa_last && pb<=pb_last){
 72         if(*pa <= *pb){
 73             *pc++ = *pa++;
 74         }else{
 75             *pc++ = *pb++;
 76         }
 77     }
 78     while(pa<=pa_last){         //插入La剩余的元素
 79         *pc++ = *pa++;          //插入Lb剩余的元素
 80     }
 81     while(pb <= pb_last){
 82         *pc++ = *pb++;
 83     }
 84 }
 85 
 86 //查看顺序表中第一个的满足compare()的元素的位序
 87 int LocateElem_Sq(SqList L, int e, int (* compare)(int x, int y)){
 88     int i = 1;
 89     int *p = L.elem;
 90     while(i <= L.length && !(*compare)(*p++, e)){
 91         ++i;
 92     }
 93     if(i <= L.length){
 94         return i;
 95     }else{
 96         return 0;
 97     }
 98 }
 99 
100 int cmp(int x, int y){
101     if(x == y){
102         //printf("x=y\n");
103         return 1;
104     }else{
105         //printf("x!=y\n");
106         return 0;
107     }
108 }
109 int main(){
110     SqList La;
111     SqList Lb;
112     SqList Lc;
113     int N,e;
114     InitList_Sq(&La);
115     printf("输入La元素的个数N:");
116     scanf("%d",&N);
117     printf("输入La的元素:");
118     while(N--){
119         scanf("%d",&e);
120         int i =La.length+1;
121         ListInsert_Sq(&La,i,e);
122     }
123     InitList_Sq(&Lb);
124     printf("输入Lb元素的个数N:");
125     scanf("%d",&N);
126     printf("输入Lb的元素:");
127     while(N--){
128         scanf("%d",&e);
129         int i =Lb.length+1;
130         ListInsert_Sq(&Lb,i,e);
131     }
132     printf("此时La中的元素顺序表的值为:");
133     for(int i=0;i<La.length;i++){
134         printf("%d ",La.elem[i]);
135     }
136     printf("\nLa.length = %d\tLa.listsize = %d\n",La.length,La.listsize);
137     printf("此时Lb中的元素顺序表的值为:");
138     for(int i=0;i<Lb.length;i++){
139         printf("%d ",Lb.elem[i]);
140     }
141     printf("\nLb.length = %d\tLb.listsize = %d\n",Lb.length,Lb.listsize);
142     ListDelete_Sq(&La,4,&e);
143     printf("删除第四个元素后La的元素顺序表的值为:");
144     for(int i=0;i<La.length;i++){
145         printf("%d ",La.elem[i]);
146     }
147     printf("\nLa.length = %d\tLa.listsize = %d\te = %d\n",La.length,La.listsize,e);
148     MergeList_Sq(La, Lb, &Lc);
149     printf("La和Lb合并后得到Lc,其Lc的信息为:\n");
150     printf("Lc的元素顺序表为:");
151     for(int i=0;i<Lc.length;i++){
152         printf("%d ",Lc.elem[i]);
153     }
154     printf("\nLc.length = %d\tLc.listsize = %d\n",Lc.length,Lc.listsize);
155     printf("输入你要在Lc中查找的元素e:");
156     scanf("%d",&e);
157     printf("该元素e在Lc的位序位:%d\n",LocateElem_Sq(Lc, e, cmp));
158   free(La.elem);free(Lb.elem);free(Lc.elem);return 0;
159 }

  结果为:

  

 

转载于:https://www.cnblogs.com/TsnTse/p/9070013.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/277960.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

校招需要看的书 巩固的知识

前言 感谢教练&#xff0c;学长们&#xff0c;队友&#xff0c;lollipop&#xff0c;猫哥&#xff0c;李哥&#xff0c;表哥&#xff0c;鸡哥&#xff0c;样样&#xff0c;咸糖&#xff0c;茗记&#xff0c;明沙&#xff0c;嘻&#xff0c;树佬(排名不分先后)等等太多太多的人的…

Teams Tab的Single Sign-On

在我写这篇文章的时候&#xff0c;这个SSO机制还是在 Developer Preview 阶段&#xff0c;可能在发布前还会有一些改进。不过我觉得这个功能很好&#xff0c;所以先和大家分享一下。 如果大家之前已经开发过Teams的tab应用&#xff0c;可能会发现如果你需要一个当前用户的toke…

算法引入

算法的概念&#xff1a; 解决问题的思路。 时间复杂度&#xff1a; 定义&#xff1a; 基本运算的执行数量。是算法效率的衡量的量。 计算准则&#xff1a; 基本操作&#xff1a;即只有常数项。复杂度认为1顺序&#xff0c;按照加法计算循环&#xff0c;按照乘法计算条件。按照最…

如何开发Teams Bot

很多朋友问我如何开发一个成功的Teams Bot&#xff0c;他们说Bot Framework SDK看起来简单&#xff0c;但是真要的去开发一款成熟的bot&#xff0c;很多地方还是不知道如何使用。我从最早的bot framework还在beta的时候开始用&#xff0c;后来framework经历了多次大的改动&…

P1579哥德巴赫猜想

写来自己学习用~ 题目内容&#xff1a; 1742年6月7日哥德巴赫写信给当时的大数学家欧拉&#xff0c;正式提出了以下的猜想&#xff1a;任何一个大于9的奇数都可以表示成3个质数之和。质数是指除了1和本身之外没有其他约数的数&#xff0c;如2和11都是质数&#xff0c;而6不是质…

在VSCode Remote环境下开发Teams Bot

我使用VS Code开发已经有蛮长一段时间了&#xff0c;时间长了&#xff0c;越来越喜欢VS Code&#xff0c;虽然有些时候会没有传统的VS方便&#xff0c;比如开发Azure Function时你需要编写一下launch.json&#xff0c;而且你需要手动启动StorageEmulator&#xff0c;但是也正是…

查看安卓APK源码破解

原文:查看安卓APK源码破解工具准备&#xff1a; <1>.android4me的AXMLPrinter2工具 <2>dex2jar <3>jd-gui 工具下载&#xff1a;http://download.csdn.net/detail/catshitone/8491347 开始&#xff1a; 第一步&#xff1a; 首先用解压软件&#xff08;如好…

Teams Bot开发系列:初识Bot

上次我们讲了Teams Bot开发的概述&#xff0c;讲了Azure Bot Service&#xff0c;Bot Framework SDK和我们自己的bot服务的概念&#xff0c;这篇文章就带大家看看Azure Bot Service和我们的bot是如何发生关系的。 我们自己开发的bot服务实际上就是一个api service&#xff0c;…

[环境搭建]SDN网络感知服务与最短路径应用

1.安装python模块networkxpip install networkx2.给Network_Awareness.py加修改权限chmod 777 Network_Awareness.py3.下载安装ryugit clone git://github.com/osrg/ryu.gitcd ryu sudo python ./setup.py install#若已安装ryu,删了再装&#xff0c; pip uninstall ryu4.修改“…

ubuntu16.04下安装opencv出现libgtk2.0-dev配置失败问题解决方法

第一次在ubuntu下安装opencv&#xff0c;遇到很多问题&#xff0c;特别是libgtk2.0-dev总是配置失败的问题&#xff0c;在网上也看到一些解决方法&#xff0c;自己也遇到一些比较奇葩的问题&#xff0c;故整理于此。 网上大部分的解决方案就是更改下载源&#xff0c;我看到一些…

03|模型I/O:输入提示、调用模型、解析输出

03&#xff5c;模型I/O&#xff1a;输入提示、调用模型、解析输出 从这节课开始&#xff0c;我们将对 LangChain 中的六大核心组件一一进行详细的剖析。 模型&#xff0c;位于 LangChain 框架的最底层&#xff0c;它是基于语言模型构建的应用的核心元素&#xff0c;因为所谓 …

selenuim自动化爬取汽车在线谷米爱车网车辆GPS数据爬虫

#为了实时获取车辆信息&#xff0c;以及为了后面进行行使轨迹绘图&#xff0c;写了一个基于selelnium的爬虫爬取了车辆gps数据。 #在这里发现selenium可以很好的实现网页解析和处理js处理 #导包 import timefrom selenium import webdriverfrom selenium.webdriver.support.wai…

Teams Bot开发系列:Activity处理流程

上篇文章介绍了什么是Activity&#xff0c;Turn&#xff0c;TurnContext和BotAdapter&#xff0c;这篇文章我们看看这些东西是如何窜起来的&#xff0c;他们是如何处理用户发给bot的消息的。 我们以一个最简单的bot&#xff0c;echo bot为例子&#xff0c;所谓的echo bot就是用…

linux下搭建go环境--问题记录

记录自己在linux上搭建go环境的经历。&#xff08;因为各种版本&#xff0c;linux系统问题挣扎了几天&#xff09; 安装vmware-tools,把我要运行代码拷进来。这个网上方法很多&#xff0c;我的电脑抽风不能安装&#xff0c;后面重装的虚拟机确定Ubuntu版本、位数。很重要&#…

Teams Bot开发系列:Bot验证

我们今天来说一下authentication&#xff0c;authentication一直是一个复杂的问题。bot里的authentication也不简单。我们先来看一个概念&#xff1a;Bot Framework Token Service&#xff0c;根据官方定义&#xff0c;这个token service主要是&#xff1a; Facilitating the u…

堆排序

目录 一、定义二、算法分析三、代码地址一、定义 1.1 堆 ​ 此处的堆&#xff0c;指数据结构中的堆。而不是内存中的那种内存堆&#xff0c;内存堆是基于数据结构的一种实现。堆的数据结构是一棵完全二叉树&#xff0c;它有如下特点&#xff1a;&#xff08;具体参考下文链接&a…

Teams Bot开发系列:Middleware

middleware是目前一些framework比较流行的概念&#xff0c;通常一个开发框架需要提供一些可扩展可定制化的功能。所以middleware这种pattern就很实用。 熟悉asp.net core的开发可能第一个想到的就是asp.net core的middleware&#xff0c;如下图&#xff1a; 当一个http reques…

ElasticSearch教程——自定义分词器(转学习使用)

一、分词器 Elasticsearch中&#xff0c;内置了很多分词器&#xff08;analyzers&#xff09;&#xff0c;例如standard&#xff08;标准分词器&#xff09;、english&#xff08;英文分词&#xff09;和chinese&#xff08;中文分词&#xff09;&#xff0c;默认是standard. s…

使用Azure Serverless来开发Teams App

Azure Function可以说比较早期的一个serverless服务&#xff0c;随着这些年云服务的大行其道&#xff0c;Serverless在概念越来越火&#xff0c;什么叫serverless&#xff1f; Serverless computing (or serverless for short), is an execution model where the cloud provide…

使用AzureFunction开发最简单的Teams Outgoing Webhook

上篇文章讲了teams app的serverless架构&#xff0c;这篇主要讲如何真正使用Azure Function来开发一个最最简单的Teams Outgoing Webhook。 我们先登入azure的portal&#xff0c;创建一个azure function。我这里创建了一个名字叫outgoing-webhook的azure function。完成后如下…