数据结构之顺序表的静态与动态对数据的运算

1.动态创建(简)

思路:

①先创建结构体,再创建结构体数组,为了方便以后修改,可以取一些别名;

②如果没有创建成功,那么要及时销毁之前所创建的堆区,防止内存泄漏;

③编写插入数据函数时需要考虑头插还是尾插,亦或者中间插入;

④编写删除函数时要考虑多个相同数据位于一堆怎么删除,连续数据位于末尾怎么删除,这里要注意越界问题;

⑤考虑是否需要用到二级指针更改实参,只更改形参是否可以达到目的;

⑥如有错误,可以用跟踪打印或者jdb调试来查找错误,例如:

132     printf("%d %s %s\n",__LINE__,__FILE__,__FUNCTIO    N__);
root@ubuntu:/mnt/U_share/DATA# ./a.out
132 seqlist.c main    //运行到这里表示没错,机器思想
root@ubuntu:/mnt/U_share/DATA# gcc seqlist.c
root@ubuntu:/mnt/U_share/DATA# ./a.out
please input increase data:1
please input increase data:1
please input increase data:2 
please input increase data:2
please input increase data:3
please input increase data:4
please input increase data:4
please input increase data:q
4 4 3 2 2 1 1 
please input delete data:1
please input delete data:q
4 4 3 2 2 
please input change pos and data:0,5
5 4 3 2 2 
the select*from:3
data:5
  1 /*===============================================
  2 *   文件名称:seqlist.c
  3 *   创 建 者:     
  4 *   创建日期:2022年07月05日
  5 *   描    述:
  6 ================================================*/
  7 #include <stdio.h>
  8 #include <stdlib.h>//malloc(),free()
  9 typedef int type;//便于更改类型,char...
 10 typedef struct data{
 11     type *data;//存放数组的首地址
 12     int len;//存放数组下标的长度
 13     int maxlen;//存放数组的最大长度
 14 }List,*pList;//*pList是定义的结构体指针,简化代码的编写

 15 //声明顺序表初始化函数(根据返回值,弊端:返回数据为-1)
 16 pList list_create(int maxlen)
 17 {
 18     //开辟顺序表 
 19     //List *p = malloc(List);
 20     pList p = malloc(sizeof(List));
 21     if(NULL==p){
 22         perror("malloc_list");
 23         return NULL;
 24     }
 25     //开辟顺序表内部数组
 26     p->data = malloc(maxlen*sizeof(type));
 27     if(NULL==p->data){
 28         perror("malloc_data");
 29         free(p);//开辟数组失败,释放结构体指针
 30         return NULL;
 31     }
 32     p->maxlen = maxlen;
 33     p->len = -1;//对应数组下标,也可以从0开始 
 34     return p;
 35 }
 36 //声明插入数据函数 
 37 int list_insert_pos(pList L,int pos,int data)
 38 {
 39    if(NULL==L)//判断顺序表L是否已经被创建
 40        return -1;
 41    //判满以及插入下标是否有效
 42    if(L->len==L->maxlen || pos<0 || pos>L->len+1){
 43         fputs("error",stdout);
 44         return -1;
 45    }
 46    L->len++;//下标加1,然后插入元素 
 47    //从最后一个元素依次右移,2插入位置停止 
 48    for(int i=L->len;i>pos;i--)
 49        L->data[i] = L->data[i-1];
 50    L->data[pos] = data;
 51    return 0;
 52 }
 53 //声明插入释放函数
 54 int list_free(pList *L)
 55 {
 56     if(NULL==*L)
 57         return -1;
 58     free((*L)->data);//释放结构体内部
 59     free(*L);//释放顺序表
 60     *L = NULL;//将指针指向空,防止隐患
 61     return 0;
 62 }
 63 //声明判满函数
 64 int list_full(pList L)
 65 {
 66     if(NULL==L)
 67         return -1;
 68     if(L->len == L->maxlen)
 69         return 0;
 70     return -1;
 71 }
 72 //声明判空函数
 73 int list_empty(pList L)
 74 {
 75     if(NULL==L)
 76         return -1;
 77     if(-1 == L->len)
 78         return 0;
 79     return -1;
 80 }
 81 //声明更改函数
 82 int list_change_pos(pList L,int pos,int data)
 83 {
 84     if(NULL==L || 0==list_empty(L))
 85         return -1;
 86     if(pos<0 || pos > L->len)
 87         return -1;
 88     L->data[pos] = data;
 89     return 0;
 90 }
 91 //声明查询函数 
 92 int list_select_pos(pList L,int pos,int *data)
 93 {
 94     if(NULL==L || 0==list_empty(L))
 95         return -1;
 96     for(int i=0;i<=L->len;i++){
 97         if(i == pos)
 98             printf("the select*from:%d\n",L->data[i]);
 99     }
100     return 0;
101 
102 }
103 //删除元素
104 int list_delete_data(pList L,int data)
105 {
106     if(NULL==L || 0==list_empty(L))
107         return -1;
108     int i=0,j;
109     while(i <= L->len){
110         if(data == L->data[i]){
111             j=i;//;为了连续删除做个标志位
112             while(j < L->len){
113                 L->data[j] = L->data[j+1];
114                 j++;
115             }
116             L->len--;
117 //为了不被遗漏元素,数组下标减1,例如偶数次元素只删除一个 
118             i--;
119         }
120         i++;
121     }
122     return 0;
123 }
124 int list_insert_pos(pList L,int pos,int data);
125 int list_delete_data(pList L,int data);
126 int list_change_pos(pList L,int pos,int data);
127 int list_select_pos(pList L,int pos,int *data);
128 int main(int argc,char argv[])
129 {
130     pList p = list_create(10);
131     type data;//上文区别名 int 
132     while(1){
133         printf("please input increase data:");
134         if(0 == scanf("%d",&data)){
135             getchar();
136             break;
137         }
138         list_insert_pos(p,0,data);//头插
139     }
140     for(int i=0;i<=p->len;i++)
141         printf("%d ",p->data[i]);
142     puts("");
143     while(1){
144         printf("please input delete data:");
145         if(0 == scanf("%d",&data)){
146             getchar();
147             break;//输入字母退出 
148         }
149         list_delete_data(p,data);
150     }
151     for(int i=0;i<=p->len;i++)
152         printf("%d ",p->data[i]);
153     puts("");
154     type j;
155     fputs("please input change pos and data:",stdout);
156     scanf("%d,%d",&j,&data);
157     list_change_pos(p,j,data);
158     for(int i=0;i<=p->len;i++)
159         printf("%d ",p->data[i]);
160     puts("");
161     list_select_pos(p,2,&data);
162     printf("data:%d\n",data);
163     return 0;
164 }

2.动态创建(繁、待改进)

#include <stdio.h>
#include <stdlib.h>
typedef int type;
typedef struct data{
    type *data;
    int len;
    int maxlen;
}Seqlist,*pSeqlist;
//创建并初始化顺序表(根据参数返回)
int list_create(pSeqlist *L,int len)
{
    (*L) = malloc(sizeof(Seqlist));
//    pSeqlist p = malloc(sizeof(Seqlist));
//    注意:返回值返回和参数返回是不一样的,返回值返回需要定义一个指针,然后会返回指针,而参数返回是以及定义好了指针只需要传就行了
    if(NULL == *L){ 
        perror("list_malloc");
        return -1;//-1或者NULL根据参数或返回值判断
    }
    (*L)->data = malloc(len*sizeof(type));
    if(NULL == (*L)->data){
        perror("data_malloc");
        free(*L);
        *L = NULL;
        return -1;
    }
    (*L)->len = -1;
    return 0;
}
//顺序表判空
int list_empty(pSeqlist L)
{
    if(NULL == L)
        return -1;
    if(-1 == L->len)
        return -1;
    return 0;
}
//顺序表判满
int list_full(pSeqlist L)
{
    if(NULL == L)
        return -1;
    if(L->len+1 == L->maxlen)//结构体成员变量的引用
        return 0;
    return -1;
}
//顺序表按位置插入元素
int list_insert_pos(pSeqlist L,int pos,type data)
{
    if(NULL == L || 0 == list_full(L))
        return -1;
    if(-1>pos || L->len<pos)
        return -1;
    L->len++;
    for(int i=L->len;i>pos;i--)//先遍历到pos处 
        L->data[i] = L->data[i-1];
    L->data[pos] = data;
    return 0;
}
//顺序表删除元素
int list_delete(pSeqlist L,type data)
{
    if(NULL==L || 0==list_empty(L))
        return -1;
    for(int i=0;i<=L->len;i++){//下标取等 
        if(data == L->data[i]){
            for(int j=i;j<L->len;j++)//越界不取等
                L->data[j] = L->data[j+1];//j+1
//那么问题来了,最后一个元素是需要删除的元素呢?
//这一步的另一个作用,如果最后一个元素需要被删除直接顺序表长度减1
            L->len--;
//为了能连续删除相同的元素,因为后面有个i++,如果不执行这一步,那么第一个需要删除元素被第二个连续需要删除元素替换后,第二个连续连续删除元素便漏了,比如1 2 2 3
            i--;
        }
    }
    return 0;
}
//顺序表展现元素
int list_show(pSeqlist L)
{
    if(NULL==L || 0==list_empty(L)){
        perror("s");
        return -1;
    }
    for(int i=0;i<=L->len;i++)
        printf("%d ",L->len);
    printf("%d,%s,%s\n",__LINE__,__FILE__,__FUNCTION__);
    puts("");
    return 0;
}
//顺序表按位置修改元素
int list_change_pos(pSeqlist L,int pos,type data)
{
    if(NULL==L || 0==list_empty(L))
        return -1;
    int i=0;
    while(i<=L->len){
        L->data[pos] = data;
        i++;
    }
    return 0;
}
//顺序表查询指定元素
int list_watch_pos(pSeqlist L,int pos,type *data)
{
    if(NULL==L || 0==list_empty(L))
        return -1;
    if(-1>pos || pos<L->len)
        return -1;
    for(int i=0;i<L->len;i++){
        if(i==pos)
            printf("the select:%d\n",L->data[i]);
    }
    return 0;
}
//释放顺序表
int list_destory(pSeqlist *L)
{
    if(NULL == *L)
        return -1;
    free((*L)->data);
    free(*L);
    return 0;
}

int list_create(pSeqlist *L,int len);
int list_empty(pSeqlist L);
int list_full(pSeqlist L);
int list_insert_pos(pSeqlist L,int pos,type data);
int list_delete(pSeqlist L,type data);
int list_show(pSeqlist L);
int list_change_pos(pSeqlist L,int pos,type data);
int list_watch_pos(pSeqlist L,int pos,type *data);
int main(int argc, char *argv[])
{ 
    type data,loc;
    pSeqlist p = NULL;
    list_create(&p,10);
    while(1){
        printf("please input insert data:");
        if(0 == scanf("%d",&data)){
            getchar();
            break;
        }
        list_insert_pos(p,0,data);
    }
    //有误,调用不了list_show()函数
    //list_show(p);
    for(int i=0;i<=p->len;i++)
        printf("%d ",p->data[i]);
    puts("");
    while(1){
        printf("please input additive loc and data:");
        if(0 == scanf("%d,%d ",&loc,&data)){
            getchar();
            break;
        }
        list_insert_pos(p,loc,data);
    }
    list_change_pos(p,3,7);
    list_show(p);
    while(1){
        printf("please input delete data:");
        if(0 == scanf("%d ",&data)){
            getchar();
            break;
        }
        list_delete(p,data);
    }
    list_show(p);
    printf("please input select data:\n");
    scanf("%d",&data);
    list_watch_pos(p,2,&data);
    list_show(p);
    list_destory(&p);
    if(NULL == p)
        fputs("this is NULL.",stdout);
    return 0;
} 

3.静态创建

#include <stdio.h>
#define Max 10;
typedef struct{
    int data[Max];
    int len;
}Seqlist,*pSeqlist;

顺序表的特点:

  1. 随机访问 ,时间复杂度为O(1)时间。
  2. 存储密度高。
  3. 拓展容量不方便。
  4. 插入、删除操作不方便,需要移动大量元素。

 <>指定根目录
""当前目录或指定目录

1.数据:信息的载体。
2.数据元素:数据的基本单位,又叫记录。
3.数据结构:数据元素及数据元素之间的相互关系,或组织数据的形式。
4.数据结构的概念:
逻辑结构:数据运算之间的抽象关系(邻接,从属)。
线性结构、非线性结构
存储结构:逻辑结构在计算机中的具体实现方法。
5.顺序存储方法、链式存储方法、索引存储方法、散列存储方法
6.数据运算:对数据进行的操作。
插入、删除、修改、查找、排序等。

数据的四种存储结构:
顺序存储结构:借助元素在存储器中的相对位置来表示逻辑关系
链式存储结构:存储指针的位置
索引存储
散列存储

7.线性结构:线性表、栈、队
非线性结构:树、图
存储:顺序、链式

8.算法:一个有穷规则(语句、指令)的有序集合。
9.算法的特性:有穷性、确定性、可行性、输入、输出
有穷性:算法执行的步骤或规则是有限的。
确定性:每个计算步骤无二义性。
可行性:每个计算步骤能够在有限的时间内完成。
输入  :算法有零个或者多个外部输入。
输出  :算法有一个或者多个输出。

10.算法分析:在算法正确的前提下,评价算法的好坏。
时间复杂度
空间复杂度    这两者结合为时空复杂度
容易理解、容易编程和调试、容易维护
11.问题规模

数据结构+算法=程序

好的算法:
算法对应的程序所耗时间少;
算法对应的程序所耗存储空间少;
算法结构性好,易读、易移植和调试等等。

12.语句的频度:在程序中重复执行的次数。
举例:冒泡排序法的时间复杂度。T(n)=n(n-1)
T(n)的量级:
O(c)、O(n)、O(n2)、O(n3)、
对数级O(log2n)、
线性对数级O(n*log2n)、
指数级O(2n),时间复杂度最差

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值