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

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

一个简单的顺序表基础操作示例
  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赋值的操作。

 

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

你可能感兴趣的:(基础)