• 顺序线性表——实验及提升训练


      1 #include <stdio.h>
      2 #include <stdlib.h>
      3 #include<stdbool.h>
      4 /*此处是顺序线性表数据结构定义*/
      5 typedef int DataType;
      6 struct seqList
      7 {//有3个数据成员
      8   int MAXNUM;//用于记录顺序线性表中能存放的最大元素个数的 整型 MAXNUM   
      9   int curNum;//用于存放顺序线性表中数据元素的个数  整型  curNum
     10   DataType *element;//用于存放顺序线性表数据元素的连续空间的起始地址  
     11 };
     12 
     13 typedef struct seqList *PseqList;
     14 int binarySearch(PseqList plist,int target, int *pos, bool lower);
     15 void searchRange(PseqList plist,int target, int *pos);
     16 /*创建空的顺序线性表,能存放的最大元素个数为 m*/
     17 PseqList createNullList_seq(int m)
     18 { //若m=0,则返回NULL 
     19     PseqList plist = (struct seqList *)malloc(sizeof(struct seqList));
     20     if(plist == NULL) return NULL; //分配空间失败
     21     plist->MAXNUM = m ;
     22     plist->curNum = 0;
     23     plist->element = (DataType *)malloc(sizeof(DataType)*m);
     24     if(plist->element == NULL) 
     25     {
     26         free(plist);
     27         return NULL;
     28     }
     29     return plist;
     30 }
     31 
     32 
     33 
     34 /*在线性表表尾插入数据元素,返回值0表示插入失败,返回值1表示在表尾插入成功*/
     35 int insertP_tail(PseqList plist , int x)
     36 {
     37     if(plist->curNum == plist->MAXNUM) //若表满,则无法插入
     38     {
     39        printf("list if full !");
     40        return 0;
     41     }
     42     plist->element[plist->curNum] = x ;
     43     plist->curNum++;
     44     return 1;
     45 
     46 }
     47 
     48 /*回收线性表占用的空间*/
     49 int destroyList_seq(PseqList plist)
     50 {
     51     //返回值为销毁的线性表中现有数据元素的个数,若待销毁的线性表不存在,则返回0
     52     if(plist == NULL) return 0;
     53     int m = plist->curNum;
     54     free(plist->element);
     55     free(plist);
     56     return m;
     57     
     58 }
     59 
     60 void printList_seq(PseqList plist)
     61 {//逐个输出线性表的元素,相邻的两个数据元素之间以一个空格为分隔符隔开
     62    for(int i=0;i<plist->curNum;i++)
     63         printf("%d ",plist->element[i]);
     64 }
     65 
     66 //第一关:求顺序线性表中连续子表(最少有一个元素)的最大和并输出
     67 int seqMaxSum(PseqList plist)
     68 { if (plist==NULL)return 0;
     69     int curSum=plist->element[0];
     70     int max=plist->element[0];
     71     for (int i = 1; i < plist->curNum; ++i) {
     72     if (curSum < 0)
     73     {
     74         curSum=plist->element[i];
     75     }else
     76     {
     77         curSum += plist->element[i];
     78     }
     79     if (curSum > max)
     80     {
     81         max=curSum;
     82     }
     83     }
     84         return max;
     85     
     86 }
     87 
     88 //第二关:寻找线性表中没有出现的最小的正整数
     89 int findMinNumber(PseqList plist)
     90 {
     91     //若线性表为空,则返回0
     92      if (plist==NULL)return 0;
     93     for (int i = 0; i < plist->curNum; ++i) {
     94         if (plist->element[i] <= 0)
     95         {
     96             plist->element[i] = plist->curNum + 1;
     97         }
     98     }
     99     for (int i = 0; i < plist->curNum; ++i) {
    100         int num = abs(plist->element[i]);
    101         if (num <= plist->curNum)
    102         {
    103             plist->element[num - 1] = -abs(plist->element[num - 1]);
    104         }
    105     }
    106     for (int i = 0; i < plist->curNum; ++i) {
    107         if (plist->element[i] > 0)
    108         {
    109             return i + 1;
    110         }
    111 
    112     }
    113     return plist->curNum + 1;
    114 }
    115 
    116 //第三关:找出给定目标值target在有序线性表中出现的起始位置和结束位置
    117 void findPos(PseqList plist,int target, int *pos)
    118 {
    119 //起始位置放在pos[0], 结束位置放在pos[1]
    120     searchRange( plist, target,  pos);
    121 
    122 }
    123 
    124 
    125 
    126 
    127 int binarySearch(PseqList plist,int target, int *pos, bool lower)
    128 {
    129     int begin = 0;
    130     int end = plist->curNum - 1;
    131     int ans = plist->curNum;
    132     while (begin <= end)
    133     {
    134         int mid = (begin+ end ) / 2;
    135         if (plist->element[mid] > target || (lower && plist->element[mid] >= target))
    136         {
    137             end = mid - 1;
    138             ans = mid;
    139         }else
    140         {
    141             begin = mid + 1;
    142         }
    143     }
    144     return ans;
    145 
    146 }
    147 void searchRange(PseqList plist,int target, int *pos)
    148 {
    149     int leftIdx = binarySearch(plist,target,pos, true);
    150     int rightIdx = binarySearch(plist,target,pos, false) - 1;
    151 
    152     if (leftIdx <= rightIdx && rightIdx < plist->curNum && plist->element[leftIdx] == target && plist->element[rightIdx] == target) {
    153         pos[0] = leftIdx, pos[1] = rightIdx;
    154         return;
    155     }
    156     pos[0] = -1, pos[1] = -1;
    157 
    158 }
    159 
    160 
    161   
    edu
      1 //
      2 // Created by keyter on 2020/12/23.
      3 //
      4 
      5 #ifndef CONTINUOUSSUBTABLESFIND_SEQLIST_H
      6 #define CONTINUOUSSUBTABLESFIND_SEQLIST_H
      7 #include <stdio.h>
      8 #include <stdlib.h>
      9 
     10 /*此处是顺序线性表数据结构定义*/
     11 typedef int DataType;
     12 struct seqList
     13 {//有3个数据成员
     14     int MAXNUM;//用于记录顺序线性表中能存放的最大元素个数的 整型 MAXNUM
     15     int curNum;//用于存放顺序线性表中数据元素的个数  整型  curNum
     16     DataType *element;//用于存放顺序线性表数据元素的连续空间的起始地址
     17 };
     18 
     19 typedef struct seqList *PseqList;
     20 int binarySearch(PseqList plist,int target, int *pos, bool lower);
     21 void searchRange(PseqList plist,int target, int *pos);
     22 /*创建空的顺序线性表,能存放的最大元素个数为 m*/
     23 PseqList createNullList_seq(int m)
     24 { //若m=0,则返回NULL
     25     PseqList plist = (struct seqList *)malloc(sizeof(struct seqList));
     26     if(plist == NULL) return NULL; //分配空间失败
     27     plist->MAXNUM = m ;
     28     plist->curNum = 0;
     29     plist->element = (DataType *)malloc(sizeof(DataType)*m);
     30     if(plist->element == NULL)
     31     {
     32         free(plist);
     33         return NULL;
     34     }
     35     return plist;
     36 }
     37 
     38 
     39 
     40 /*在线性表表尾插入数据元素,返回值0表示插入失败,返回值1表示在表尾插入成功*/
     41 int insertP_tail(PseqList plist , int x)
     42 {
     43     if(plist->curNum == plist->MAXNUM) //若表满,则无法插入
     44     {
     45         printf("list if full !");
     46         return 0;
     47     }
     48     plist->element[plist->curNum] = x ;
     49     plist->curNum++;
     50     return 1;
     51 
     52 }
     53 
     54 /*回收线性表占用的空间*/
     55 int destroyList_seq(PseqList plist)
     56 {
     57     //返回值为销毁的线性表中现有数据元素的个数,若待销毁的线性表不存在,则返回0
     58     if(plist == NULL) return 0;
     59     int m = plist->curNum;
     60     free(plist->element);
     61     free(plist);
     62     return m;
     63 
     64 }
     65 
     66 void printList_seq(PseqList plist)
     67 {//逐个输出线性表的元素,相邻的两个数据元素之间以一个空格为分隔符隔开
     68     for(int i=0;i<plist->curNum;i++)
     69         printf("%d ",plist->element[i]);
     70 }
     71 
     72 //第一关:求顺序线性表中连续子表(最少有一个元素)的最大和并输出
     73 int seqMaxSum(PseqList plist)
     74 {
     75     if (plist==NULL)return 0;
     76     int curSum=plist->element[0];
     77     int max=plist->element[0];
     78     for (int i = 1; i < plist->curNum; ++i) {
     79     if (curSum < 0)
     80     {
     81         curSum=plist->element[i];
     82     }else
     83     {
     84         curSum += plist->element[i];
     85     }
     86     if (curSum > max)
     87     {
     88         max=curSum;
     89     }
     90     }
     91         return max;
     92 }
     93 
     94 //第二关:寻找线性表中没有出现的最小的正整数
     95 int findMinNumber(PseqList plist)
     96 {//hashTable
     97     /*对于「前言」中提到的第一种做法:
     98 
     99 我们可以将数组所有的数放入哈希表,随后从 11 开始依次枚举正整数,并判断其是否在哈希表中。
    100 
    101 仔细想一想,我们为什么要使用哈希表?这是因为哈希表是一个可以支持快速查找的数据结构:给定一个元素,我们可以在 O(1)O(1) 的时间查找该元素是否在哈希表中。因此,我们可以考虑将给定的数组设计成哈希表的「替代产品」。
    102 
    103 实际上,对于一个长度为 NN 的数组,其中没有出现的最小正整数只能在 [1, N+1][1,N+1] 中。这是因为如果 [1, N][1,N] 都出现了,那么答案是 N+1N+1,否则答案是 [1, N][1,N] 中没有出现的最小正整数。这样一来,我们将所有在 [1, N][1,N] 范围内的数放入哈希表,也可以得到最终的答案。而给定的数组恰好长度为 NN,这让我们有了一种将数组设计成哈希表的思路:
    104 
    105 我们对数组进行遍历,对于遍历到的数 xx,如果它在 [1, N][1,N] 的范围内,那么就将数组中的第 x-1x−1 个位置(注意:数组下标从 00 开始)打上「标记」。在遍历结束之后,如果所有的位置都被打上了标记,那么答案是 N+1N+1,否则答案是最小的没有打上标记的位置加 11。
    106 
    107 那么如何设计这个「标记」呢?由于数组中的数没有任何限制,因此这并不是一件容易的事情。但我们可以继续利用上面的提到的性质:由于我们只在意 [1, N][1,N] 中的数,因此我们可以先对数组进行遍历,把不在 [1, N][1,N] 范围内的数修改成任意一个大于 NN 的数(例如 N+1N+1)。这样一来,数组中的所有数就都是正数了,因此我们就可以将「标记」表示为「负号」。算法的流程如下:
    108 
    109 我们将数组中所有小于等于 00 的数修改为 N+1N+1;
    110 
    111 我们遍历数组中的每一个数 xx,它可能已经被打了标记,因此原本对应的数为 |x|∣x∣,其中 |\,|∣∣ 为绝对值符号。如果 |x| in [1, N]∣x∣∈[1,N],那么我们给数组中的第 |x| - 1∣x∣−1 个位置的数添加一个负号。注意如果它已经有负号,不需要重复添加;
    112 
    113 在遍历完成之后,如果数组中的每一个数都是负数,那么答案是 N+1N+1,否则答案是第一个正数的位置加 11。
    114 
    115 作者:LeetCode-Solution
    116 链接:https://leetcode-cn.com/problems/first-missing-positive/solution/que-shi-de-di-yi-ge-zheng-shu-by-leetcode-solution/
    117 来源:力扣(LeetCode)
    118 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。*/
    119     //若线性表为空,则返回0
    120     if (plist==NULL)return 0;
    121     for (int i = 0; i < plist->curNum; ++i) {
    122         if (plist->element[i] <= 0)
    123         {
    124             plist->element[i] = plist->curNum + 1;
    125         }
    126     }
    127     for (int i = 0; i < plist->curNum; ++i) {
    128         int num = abs(plist->element[i]);
    129         if (num <= plist->curNum)
    130         {
    131             plist->element[num - 1] = -abs(plist->element[num - 1]);
    132         }
    133     }
    134     for (int i = 0; i < plist->curNum; ++i) {
    135         if (plist->element[i] > 0)
    136         {
    137             return i + 1;
    138         }
    139 
    140     }
    141     return plist->curNum + 1;
    142 }
    143 
    144 //第三关:找出给定目标值target在有序线性表中出现的起始位置和结束位置
    145 void findPos(PseqList plist,int target, int *pos)
    146 {
    147 //起始位置放在pos[0], 结束位置放在pos[1]
    148     searchRange( plist, target,  pos);
    149 
    150 }
    151 
    152 
    153 
    154 
    155 int binarySearch(PseqList plist,int target, int *pos, bool lower)
    156 {
    157     int begin = 0;
    158     int end = plist->curNum - 1;
    159     int ans = plist->curNum;
    160     while (begin <= end)
    161     {
    162         int mid = (begin+ end ) / 2;
    163         if (plist->element[mid] > target || (lower && plist->element[mid] >= target))
    164         {
    165             end = mid - 1;
    166             ans = mid;
    167         }else
    168         {
    169             begin = mid + 1;
    170         }
    171     }
    172     return ans;
    173 
    174 }
    175 void searchRange(PseqList plist,int target, int *pos)
    176 {
    177     int leftIdx = binarySearch(plist,target,pos, true);
    178     int rightIdx = binarySearch(plist,target,pos, false) - 1;
    179 
    180     if (leftIdx <= rightIdx && rightIdx < plist->curNum && plist->element[leftIdx] == target && plist->element[rightIdx] == target) {
    181         pos[0] = leftIdx, pos[1] = rightIdx;
    182         return;
    183     }
    184     pos[0] = -1, pos[1] = -1;
    185 
    186 }
    187 
    188 
    189 #endif //CONTINUOUSSUBTABLESFIND_SEQLIST_H
    clion
  • 相关阅读:
    架构探险笔记3-搭建轻量级Java web框架
    软件工程
    Mysql基础
    Navicat快捷键
    百度搜索的使用技巧
    利用adb截图然后传到电脑
    Div不用float布局
    安卓开发之ScrollView
    安卓开发ScrollView嵌套ListView只显示一行
    修改eclipse的背景色(转载)
  • 原文地址:https://www.cnblogs.com/jeseesmith/p/14181204.html
Copyright © 2020-2023  润新知