zoukankan      html  css  js  c++  java
  • 一个简单的顺序表基础操作示例

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

      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)
    ");
     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("选择位置插入一项:(位置 值)
    ");
     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项。
    ", pos);
     65             else
     66                 printf("无法找到!
    ");
     67             break;
     68             //transpose:
     69         case 5:
     70             Transpose(L);
     71             Travel(L);
     72             break;
     73             //max
     74         case 6:
     75             printf("最大值是%d。
    ", 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("
    ");
    228         }
    229         printf("
    ");
    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赋值的操作。

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

  • 相关阅读:
    禾匠 运行h5
    禾匠 前端用户中心显示隐藏菜单
    禾匠 创建新插件
    芸众如何查看前端版本
    查看电脑内存条个数 和 内存是ddr几代
    yii框架中的andFilterWhere 和 andWhere的区别
    mysql 5.7之前版本截取json字符串的值
    FTP上传文件总是上传一半就断掉
    Java中如何保证线程安全性
    Java8内存结构解读
  • 原文地址:https://www.cnblogs.com/cjw1115/p/4336922.html
Copyright © 2011-2022 走看看