一个简单的顺序表基础操作示例

最近学计算机软件基础,学到了线性表。下面就将线性表中最简单的顺序表的一个简单示例贴出,方便大家探讨。(以及后面对函数传参的一个小分析,其实这才是重点)

  1 ////需求分析
  2 //1、线性表递增有序,删除重复元素
  3 //2、线性表逆置
  4 //3、寻求最大值
  5
  6 #include<stdio.h>
  7
  8 typedef int ElementType;
  9 typedef struct _struct
 10 {
 11     ElementType SequenceList[100];
 12     ElementType num;
 13 }SequenceList;
 14
 15 void InitSeq(SequenceList **L);//初始化线性表,主要是返回一个SequenceList实例,采用malloc动态开辟内存方式。
 16 int Add(SequenceList *L, ElementType value);//想列表中添加项目
 17 void Insert(SequenceList *L ,ElementType pos, ElementType value);//插入一个元素
 18 void Delete(SequenceList *L, ElementType value);//删除一个元素
 19 ElementType Search(SequenceList *L, ElementType value);//搜索一个元素
 20 void RemoveRepetiton(SequenceList *L);//移除所有重复的元素
 21 void Transpose(SequenceList *L);//将所有元素位置倒置
 22 ElementType MaxValue(SequenceList *L);//求出元素中最大值
 23 void Travel(SequenceList *L);//遍历整个列表(把每个元素都输出一遍)
 24
 25 int main()
 26 {
 27     SequenceList *L;
 28     InitSeq(&L);
 29     while (1)
 30     {
 31         int n = 0;
 32         int pos;
 33         ElementType value;
 34         printf("请选择操作:(1.Add  2.insert  3.delete  4.search  5.transpose  6.maxium  7.travel 8.removeReptitons)\n");
 35         scanf("%d", &n);
 36         switch (n)
 37         {
 38             //add
 39         case 1:
 40
 41             printf("添加新项:");
 42             scanf("%d", &value);
 43             Add(L, value);
 44             break;
 45             //insert
 46         case 2:
 47
 48             printf("选择位置插入一项:(位置 值)\n");
 49             scanf("%d %d", &pos,&value);
 50             Insert(L,pos, value);
 51             break;
 52             //delete:
 53         case 3:
 54             printf("输入删除内容:");
 55             scanf("%d", &value);
 56             Delete(L, value);
 57             break;
 58             //Search
 59         case 4:
 60             printf("搜索内容:");
 61             scanf("%d", &value);
 62             pos = Search(L, value);
 63             if (pos)
 64                 printf("存在于第%d项。\n", pos);
 65             else
 66                 printf("无法找到!\n");
 67             break;
 68             //transpose:
 69         case 5:
 70             Transpose(L);
 71             Travel(L);
 72             break;
 73             //max
 74         case 6:
 75             printf("最大值是%d。\n", MaxValue(L));
 76             break;
 77         case 7:
 78             Travel(L);
 79             break;
 80         case 8:
 81             RemoveRepetiton(L);
 82             break;
 83         default:
 84             break;
 85         }
 86     }
 87     free(L);
 88     return 0;
 89 }
 90 void InitSeq(SequenceList **L)
 91 {
 92     *L = (SequenceList *)malloc(sizeof(SequenceList));
 93     (*L)->num = -1;
 94 }
 95
 96 int Add(SequenceList *L, ElementType value)
 97 {
 98     L->num++;
 99     if (L->num >= 100)
100     {
101         L->num--;
102         printf("空间已满!");
103         return 0;
104     }
105     L->SequenceList[L->num] = value;
106     return 1;
107 }
108
109 void Insert(SequenceList *L, ElementType pos, ElementType value)
110 {
111     if (L->num<0||L->num >= 99)
112     {
113         printf("空间已满或不足!");
114         return 0;
115     }
116     if (pos-1 < 0 || pos-1 > L->num)
117     {
118         printf("插入位置错误!");
119         return;
120     }
121     int i;
122     for (i = L->num; i >= pos-1; i--)
123     {
124         L->SequenceList[i+1] = L->SequenceList[i];
125     }
126     L->SequenceList[pos - 1] = value;
127     L->num++;
128 }
129
130 void Delete(SequenceList *L, ElementType value)
131 {
132     if (L->num < 0)
133     {
134         printf("表为空!");
135         return;
136     }
137     int i;
138     for (i = 0; i <= L->num; i++)
139     {
140         if (value == L->SequenceList[i])
141         {
142             int j;
143             for (j = i; j < L->num; j++)
144             {
145                 L->SequenceList[j] = L->SequenceList[j + 1];
146             }
147             L->num--;
148         }
149     }
150 }
151
152 ElementType Search(SequenceList *L, ElementType value)
153 {
154     if (L->num<0)
155     {
156         printf("表空!");
157         return -1;
158
159     }
160     else
161     {
162         int i;
163         for (i = 0; i <= L->num; i++)
164         {
165             if (value == L->SequenceList[i])
166                 return i + 1;
167         }
168     }
169
170     return 0;
171 }
172
173 void RemoveRepetiton(SequenceList *L)
174 {
175     int count=0;
176     int i;
177     for (i = 0; i <= L->num; i++)
178     {
179         if (Search(L, L->SequenceList[i]))
180         {
181             Delete(L, L->SequenceList[i]);
182             count++;
183         }
184     }
185     printf("共删除了%d项。", count);
186 }
187
188 void Transpose(SequenceList *L)
189 {
190     ElementType *temp = (ElementType *)malloc(sizeof(ElementType)*(L->num + 1));
191     int i ,j;
192     for (i = L->num, j = 0; i >= 0; i--,j++)
193     {
194         temp[j] = L->SequenceList[i];
195     }
196     for (i = 0; i <= L->num; i++)
197     {
198         L->SequenceList[i] = temp[i];
199     }
200     free(temp);
201 }
202 ElementType MaxValue(SequenceList *L)
203 {
204     int i = 0;
205     ElementType max = L->SequenceList[0];
206     for (i = 1; i <= L->num; i++)
207     {
208         if (max < L->SequenceList[i])
209         {
210             max = L->SequenceList[i];
211         }
212     }
213     return max;
214 }
215
216 void Travel(SequenceList *L)
217 {
218     if (L->num < 0)
219         printf("表空!");
220     else
221     {
222         int i;
223         for (i = 0; i <= L->num; i++)
224         {
225             printf("%d    ", L->SequenceList[i]);
226             if (i>0&&(i % 10 == 0))
227                 printf("\n");
228         }
229         printf("\n");
230     }
231 }

点击查看代码

代码纯手打,不是网上copy过来的。。

代码中没什么算法,搜索、删除等都用的最简单的方式。

代码中唯一值得注意的就是初始化列表的函数InitList(SequenceList **L),传的是二级指针做参数,为什么这么做呢?

下面解释一下:

我们的目的是在函数InitList中malloc一块内存空间,用于存放我们的数据。

现在先看我们常写的一个错误写法

//请看如下错误代码,这是为说明问题的错误代码
void InitList(SequenceList *L)
{
L=(SequenceList *)malloc(sizeof(SequenceList));//语法重点。。
L->num=-1;//这个是程序功能的一部分
}

许多的初学者认为我们传到函数InitList中的是一个指针变量,在InitList中可以对该指针变量进行赋值操作,以便达到修改主函数中变量的目的,于是乎便将malloc开辟的空间首地址赋给L,然后在主函数中对L操作的时候发现要么是乱码,要么是不可访问之类的错误,百思不得其解,为什么呢?

原因很简单,就是对函数参数的传递方式不明确造成的。在此处应该记着,函数传参始终是将你所传变量复制后的副本传进去,并不是该变量本身。

代入这个实际问题,我们在主函数中做如下操作

//为错误情况的示例代码,切记void main()
{
SequenceList *L;
InitList(L);
......
}

我们为函数InitList传递的是一个SequenceList类型的指针变量L,假设L此时指向内存0x10000,则在实际传参数的时候,系统会对L变量作一个复制操作,假设这儿使复制后的变量为P,则P指向的地址也为L指向的地址0x10000。

现在重点来了,我们为InitList传递参数L,但系统实际传递的参数是P(P是L的副本,他们指向同一块内存区域,但他们各自的地址不同),在函数InitList内部,则实际是对P变量进行操作,把malloc的地址(假设为0x30000)赋值给P,

所以P指向的地址是0x30000,但是主函数中的L仍然指向0x10000,所以就造成了我们遇见的错误,因为我们根本没有把L指向的地址改为malloc的地址;

那么接下来看正确的操作。

//以下代码为正确代码
void main()
{
SequenceList *L;
InitList(&L);

}
void InitSeq(SequenceList **L)
{
	*L = (SequenceList *)malloc(sizeof(SequenceList));
	(*L)->num = -1;
}

我们传参数的时候传的是变量L的地址,那么系统实际传的是变量P,P与L有如下关系:P=&L(P指向变量L的地址).在函数InitList中

*L = (SequenceList *)malloc(sizeof(SequenceList));

L是P,*L即是主函数中的L,现在用malloc的地址给*L,就实现了为主函数中L赋值的操作。

明白了吗?这是我个人的理解。可能系统在某些细节上和我说的不一样,但我这个思路应该是没错的。

时间: 2024-10-06 14:54:46

一个简单的顺序表基础操作示例的相关文章

顺序表 其他操作

1 实验2 顺序表其它操作 2 实验目的 3 1.进一步掌握在线性表的顺序存储结构上的一些其它操作. 4 实验内容 5 程序1 6 已知一个线性表,用另辟空间和利用原表两种方法把线性表逆置. 7 设计要求:在程序中构造三个子程序分别为 8 SeqList reverse(SeqList A) /*顺序表的就地逆置 */ 9 void ListTraverse(SeqList L) /* 遍历顺序表 */ 10 SeqList create(int n) /* 建立顺序表 */ 11 12 程序2

07、顺序表的操作

顺序表的操作 一.从顺序表中删除具有最小值的元素 /* 时间:2017年7月2日10:49:39 功能:从顺序表中删除具有最小值的元素并将最后元素放于被删除元素的位置,由函数返回被删元素的值 */ #include "stdio.h" #include "string.h" #include"stdlib.h" #define maxSize 15 //显式地定义表的长度 typedef int DataType; //定义表元素的数据类型 ty

数据结构——顺序表及其操作

今天总结了一下顺序表的一些操作实现,算是这个本该上而没有上的体育课的一些小收获吧! BTW,青轴用起来是爽,但时间长了感觉自己的手指痛的不行呀/TOT/~~ 1 #include<iostream> 2 3 using namespace std; 4 5 #define MAXSIZE 100 //最大长度 6 #define OK 1 7 #define ERROR -1 8 9 10 //类型重命名 11 typedef int Elemtype; 12 typedef int Stat

Java 3:顺序表的操作

顺序表常见操作有插入.删除.查找.修改.一.插入:1.插入有头插.尾插.任意位置插入.在插入时要注意下标的取值在顺序表长度范围内.所以最好在插入之前进行扩容操作.2.在头插时要注意先将原数组的元素从后往前依次向后移动.因为如果从前往后开始移动的话,会造成后一个元素被前一个元素覆盖,而丢失数据且造成重复.arr[i+1]=arr[i],注意此处i的意思是要移动的元素的下标.3.任意位置插入与头插类似,从后往前(要插入的位置元素下标)依次向后移动,再将数据插入二.删除1.删除有头删.尾删.任意位置删

一个简单的微安表

这是一个用STM8S103F3P6单片机和一个LM358运算放大器制作的一个简单的微安表,可以用来测量1mA以下的小电流,分辨率是1uA.接通电源就开始测量. 开机时的工作电流是15mA,使用9V层叠电池供电.电路板: 内部图片: 电路图在最后一页.原理很简单,通过一个100欧的电阻对待测电流取样,经过一个LM358放大50倍后送到单片机进行AD转换.这个单片机的电源电压为5V,AD分辨率10位.设进来的电流为A微安,理论上AD的读数X可以通过下式得到: X = 100*A*50*2^10/(5

C++数据结构与算法_2_线性表 --顺序表的应用示例

h2.western { font-family: "Liberation Sans",sans-serif; font-size: 16pt; }h2.cjk { font-family: "微软雅黑"; font-size: 16pt; }h2.ctl { font-family: "AR PL UMing CN"; font-size: 16pt; }h1 { margin-bottom: 0.21cm; }h1.western { fon

数据结构学习1:实现一个简单的线性表功能

数据结构: 一个简单的线性表的实现 学习了数据结构有一段时间了,那是半年前老师课堂上讲的,最后由于一些原因,没能听到最后,前几天在写一些算法的时候,发现自己的数据结构还是太渣了,因此便又拿起了那本很有价值的数据结构的书,重新来啃这本厚厚的书,数据结构在我们编程中是非常的重要的,希望这次的学习能有一个好的开头,并且能在这个过程中有所得吧! 下面是我写的一个简单的线性表的实现: #include"stdafx.h" #include<iostream> using namesp

顺序表一系列操作

在顺序表中,每个结点的存储地址是该结点在表中的位置的线性函数,是一种随机存取结构.顺序表是用向量实现的线性表,向量的下标可以看作结点的相对地址.因此顺序表的的特点是逻辑上相邻的结点其物理位置亦相邻.下面对顺序表进行头插.头删.尾插.尾删.指定位置插入数据.查找数据位置.删除某一个数.折半查找.冒泡排序和选择排序等操作并进行测试. 头函数: #define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> #include<stdlib.h> #

设计一个算法将一个顺序表逆置

#include<iostream> #include<malloc.h> using namespace std; typedef struct { int length;//保存长度 int data[40];//数组 } SqList; /*算法1:设计一个高效的算法,将顺序表中的所有元素逆置.要求算法空间股咋度为o(1)*/ //初始化顺序表 void initReverse(SqList &s,int *a,int l){ s.length=0; //插入元素 f