前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >线性表

线性表

作者头像
DeROy
发布2020-05-11 11:35:36
4640
发布2020-05-11 11:35:36
举报
文章被收录于专栏:编程学习基地

顺序表

什么是顺序表

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

定义顺序表结构体
代码语言:javascript
复制
typedef struct list
{
    int *arr;//申请堆内存,存放数据
    int len;//表中元素个数
    int size;//表中大小
}LIST;
LIST mylist;
  • 定义函数初始化顺序表
代码语言:javascript
复制
void Init(LIST *p)//初始化
{
    p->len = 0;
    p->size = 0;
    p->arr = (int *)malloc(sizeof(int)*p->size);
}
插入数据
代码语言:javascript
复制
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++;
}
删除数据
代码语言:javascript
复制
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
}
查询数据
代码语言:javascript
复制
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
}
完整代码
代码语言:javascript
复制
#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. 一行看起来有点逼格的代码
代码语言:javascript
复制
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的容量

关键字【线性表】

End

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-04-02,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 编程学习基地 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 什么是顺序表
  • 定义顺序表结构体
  • 插入数据
  • 删除数据
  • 查询数据
  • 完整代码
  • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档