原创 DeRoy 编程学习基地 2020-04-02

收录于话题

#C

92个

线性表_C语言

点击蓝字 关注我们


线性表




前言





我找个了我好久以前写的代码,和最早发布的那些项目一样,定义变量都不带经过大脑思考的,不过这个线性表涵盖的知识还是蛮多的,可以参考下,明天接着发链表,然后循环双链表,接着发双链表的应用、
代码毕竟很久以前写的,不喜勿喷~
还有就是我会记得写总结,总结下这篇推送写了个什么东西、




目录




顺序表什么是顺序表定义顺序表结构体插入数据删除数据查询数据完整代码总结

顺序表

什么是顺序表

数据在内存中依次存放,存放在动态数组中

定义顺序表结构体
typedef struct list
{

    int *arr;//申请堆内存,存放数据
    int len;//表中元素个数
    int size;//表中大小
}LIST;
LIST mylist;


  • 定义函数初始化顺序表


void Init(LIST *p)//初始化
{
    p->len = 0;
    p->size = 0;
    p->arr = (int *)malloc(sizeof(int)*p->size);
}
插入数据
void addDate(LIST*p, int date)//插入数据
{
    if (p->len >= p->size)
    {
        //内存不够 重新申请内存 
        p->size += (p->size >> 1) > 1 ? p->size >> 1 : 1;
        if (p->arr == NULL)
            p->arr = (int*)malloc(sizeof(int)*p->size);
        else
            p->arr = (int *)realloc(p->arr, sizeof(int)*p->size);
    }
    //开始插入
    //p->arr[p->len] = date;//date插入到末尾
    //p->len++;

    //插入排序
    int i;
    for (i = p->len - 1; data < p->arr[i] && i >= 0; i--)
    {
        p->arr[i + 1] = p->arr[i];
    }
    p->arr[i + 1] = data;
    p->len++;
}
删除数据
void deleDate(LIST*p, int date)
{
#if 0
    //遍历顺序表中的每一个元素,查找要删除的额元素
    for (int i = 0; i < p->len; i++)
    {
        if (p->arr[i] == date)
        {
            for (int j = i; j < p->len-1; j++)
            {
                p->arr[j] = p->arr[j + 1];
            }
            p->len--;//删除一个元素,长度减一
            i--;
        }
    }
#else
    //删除多个中的一个
    for (int i = 0; i < p->len; i++)
    {
        if (p->arr[i] == date)
        {
            printf("%d\t%d\n", i+1,p->arr[i]);
        }
    }
    printf("输入你想要删除的一个元素的序号:");
    int x;
    scanf("%d", &x);
    for (int j = x - 1; j < p->len - 1; j++)
    {
        p->arr[j] = p->arr[j + 1];
    }
    p->len--;
#endif
}
查询数据
void findDate(LIST*p, int date)
{
#if FLAG    //FLAG为真代表无序插入,无序查找
    for (int i = 0; i < p->len; i++)
    {
        if (p->arr[i] == date)
        {
            printf("%d\t%d\n", i + 1, p->arr[i]);
        }
    }
#else
    //二分查找 有序
    int left = 0, right = p->len - 1;
    int mid = (left + right) / 2;
    while (left <= right)
    {
        //数据有序  从小到大
        if (p->arr[mid] > date)
        {
            right = mid - 1;
            mid = (left + right) / 2;
        }
        else if (p->arr[mid] < date)
        {
            left = mid + 1;
            mid = (left + right) / 2;
        }
        else
            break;
    }
    printf("%d\t%d\n", mid + 1, p->arr[mid]);
#endif
}
完整代码
#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
#include<windows.h>
#define FLAG 1    //真:无序插入 假:有序插入

typedef struct list
{

    int *arr;   //申请堆内存,存放数据
    int len;    //表中元素个数
    int size;   //表中大小
}LIST;
LIST mylist;
void Init(LIST *p)//初始化
{
    p->len = 0;
    p->size = 0;
    p->arr = (int *)malloc(sizeof(int)*p->size);
}
void menu()
{
    printf("1.添加数据.\n");
    printf("2.删除数据.\n");
    printf("3.查找数据.\n");
    printf("4.插入数据.\n");
    printf("5.显示数据.\n");
}
void addDate(LIST*p, int data)//插入数据
{
    if (p->len >= p->size)
    {
        //内存不够 重新申请内存 
        p->size += (p->size >> 1) > 1 ? p->size >> 1 : 1;
        if (p->arr == NULL)
            p->arr = (int*)malloc(sizeof(int)*p->size);
        else
            p->arr = (int *)realloc(p->arr, sizeof(int)*p->size);
    }
    //开始插入
#if FLAG
    p->arr[p->len] = data;//date插入到末尾
    p->len++;
#else
    //插入排序   1 3 5 7  4
    int i;
    for (i = p->len - 1; data < p->arr[i] && i >= 0; i--)
    {
        p->arr[i + 1] = p->arr[i];
    }
    p->arr[i + 1] = data;
    p->len++;
#endif
}
void deleDate(LIST*p, int date)
{
#if 0
    for (int i = 0; i < p->len; i++)
    {
        if (p->arr[i] == date)
        {
            for (int j = i; j < p->len - 1; j++)
            {
                p->arr[j] = p->arr[j + 1];
            }
            p->len--;//删除一个元素,长度减一
            i--;
        }
    }
    //删除多个中的一个
#else
    //删除多个中的一个
    for (int i = 0; i < p->len; i++)
    {
        if (p->arr[i] == date)
        {
            printf("%d\t%d\n", i + 1, p->arr[i]);
        }
    }
    printf("输入你想要删除的一个元素的序号:");
    int x;
    scanf("%d", &x);
    for (int j = x - 1; j < p->len - 1; j++)
    {
        p->arr[j] = p->arr[j + 1];
    }
    p->len--;
#endif
}
void findDate(LIST*p, int date)
{
#if FLAG
    for (int i = 0; i < p->len; i++)
    {
        if (p->arr[i] == date)
        {
            printf("%d\t%d\n", i + 1, p->arr[i]);
        }
    }
#else
    //二分查找 有序
    int left = 0, right = p->len - 1;
    int mid = (left + right) / 2;
    while (left <= right)
    {
        //数据有序  从小到大
        if (p->arr[mid] > date)
        {
            right = mid - 1;
            mid = (left + right) / 2;
        }
        else if (p->arr[mid] < date)
        {
            left = mid + 1;
            mid = (left + right) / 2;
        }
        else
            break;
    }
    printf("%d\t%d\n", mid + 1, p->arr[mid]);
#endif
}
int FindData(LIST*p, int left, int right, int data)
{
    //递归查找
    if (left > right) return -1;
    int mid = (left + right) / 2;
    if (p->arr[mid] > data) return FindData(p, left, mid - 1, data);
    else if (p->arr[mid] > data) return FindData(p, mid + 1, right, data);
    else return mid;
}
void show(LIST*p)
{
    printf("顺序表:\n");
    for (int i = 0; i < p->len; i++)
    {
        printf("%d\t%d", i + 1, p->arr[i]);
    }
    printf("\n");
}
void insertDate(LIST*p, int date)
{
    int x;
    show(p);
    printf("请输入插入位置:");
    scanf("%d", &x);

    if (p->len >= p->size)
    {
        //内存不够 重新申请内存 
        p->size += (p->size >> 1) > 1 ? p->size >> 1 : 1;   //分配比原先大1/2的空间
        if (p->arr == NULL)
            p->arr = (int*)malloc(sizeof(int)*p->size);
        else
            p->arr = (int *)realloc(p->arr, sizeof(int)*p->size);
    }

    int j;
    for (j = p->len - 1; j >= x - 1; j--)
    {
        p->arr[j + 1] = p->arr[j];
    }
    p->arr[j + 1] = date;
    p->len++;

}
void FreeList(LIST *p)
{
    if (p->arr != NULL)
    {
        free(p->arr);
        p->arr = NULL;
    }
}
int main()
{
    int x;
    char ch;
    Init(&mylist);
    while (1)
    {
        menu();
        ch = getch();
        if (ch == '0')break;
        switch (ch)
        {
        case'1':
            printf("请输入要添加的数字:");
            scanf("%d", &x);
            addDate(&mylist, x);
            printf("按任意键继续.\n");
            ch = getch();
            system("cls");
            break;
        case'
2':
            printf("请输入要删除的数字:");
            scanf("%d", &x);
            deleDate(&mylist, x);
            printf("按任意键继续.\n");
            ch = getch();
            system("cls");
            break;
        case'3':
            printf("请输入要查找的数字:");
            scanf("%d", &x);
            //普通查找数据
            findDate(&mylist, x);
            //递归查找数据
            //int index = FindData(&mylist, 0, mylist.len, x);
            //printf("第%d个数字\t%d\n", index + 1, mylist.arr[index]);
            printf("按任意键继续.\n");
            ch = getch();
            system("cls");
            break;
        case'
4':
            printf("请输入要插入的数字:");
            scanf("%d", &x);
            insertDate(&mylist, x);
            ch = getch();
            system("cls");
            break;
        case'5':
            show(&mylist);
            printf("按任意键继续.\n");
            ch = getch();
            system("cls");
            break;
        default:continue;
        }
    }
    return 0;
}
总结
  1. 内存重分配realloc,或许用得少,但是这东西谁又能说得准呢

  2. 插入排序,在插入数据的时候进行插入排序

  3. 二分查询数据

  4. 递归查询数据

  5. 一行看起来有点逼格的代码

p->size += (p->size >> 1) > 1 ? p->size >> 1 : 1;
初始化Init之后size=0 ,代入上式 size = size + (size/2)>1?size/2:1;
等同:size = 0 + 0>1?0:1;    所以size = 1;
size = 1 再代入size = size + (size/2)>1?size/2:1;
等同:size = 1 + 0>1?0:1;  所以size = 2;
size = 2 再代入size = size + (size/2)>1?size/2:1;
等同:size = 2 + 1>1?1:1;  所以size = 3;
size = 3 再代入size = size + (size/2)>1?size/2:1;
等同:size = 3 + 1>1?1:1;  所以size = 4;
size = 4 再代入size = size + (size/2)>1?size/2:1;
等同:size = 4 + 2>1?2:1;  所以size = 6;
此后size每次都加上原先1/2的容量