C语言顺序表

简介: C语言顺序表

C语言顺序表

简介:本文是我学习数据结构期间,用C语言所写的顺序表。

ASet.h

#ifndef _ASet_h_
#define _ASet_h_
#include "Element.h"
#define ASetInitSize 1024
#define ASetIncrement 128
typedef struct
{
    int size, cardinal;
    ELEMENT *element;
} ASET;
void ASetCreate(ASET *set);
void ASetDestroy(ASET *set);
void ASetResize(ASET *set, int size);
int ASetFind(const ASET *set, const ELEMENT *element);
int ASetExist(const ASET *set, const ELEMENT *element);
void ASetAppend(ASET *set, const ELEMENT *element);
void ASetOutput(const ASET *set);
void ASetRemove(ASET *set, const ELEMENT *element);
void ASetClear(ASET *set);
void ASetInput(ASET *set);
int ASetEmpty(const ASET *set);
int ASetCardinal(const ASET *set);
ASET* ASetAssign(ASET *dst, const ASET *src);
ASET* ASetMul(ASET *dst, const ASET *src1, const ASET *src2);
SET* ASetAdd(ASET *dst, const ASET *src1, const ASET *src2);
ASET* ASetSub(ASET *dst, const ASET *src1, const ASET *src2);
int ASetGt(const ASET *set1, const ASET *set2);
int ASetGe(const ASET *set1, const ASET *set2);
int ASetLt(const ASET *set1, const ASET *set2);
int ASetLe(const ASET *set1, const ASET *set2);
int ASetEq(const ASET *set1, const ASET *set2);
int ASetNe(const ASET *set1, const ASET *set2);
#endif

Aset.c

创建集合

void ASetCreate(ASET *set)
{
  set->size = ASetInitSize;
  set->element = (ELEMENT *) malloc (sizeof (ELEMENT) * set->size);
  set->cardinal = 0;
}

销毁集合

void ASetDestroy(ASET *set)
{
  set->size = 0;
  set->cardinal = 0;
  free(set->element);
  set->element = NULL; 
}

改变动态数组尺寸

void ASetResize(ASET *set, int size)
{
  if (size >= set->cardinal && size != set->size)
  {
    ELEMENT *a;
    a = (ELEMENT *) malloc (sizeof (ELEMENT) * size);
    int i;
    for (i = 0; i < set->cardinal; i++)
    {
      a[i] = set->element[i];
    }
    set->size = size;
    free(set->element);
    set->element = a;
  }
}

查找元素

int ASetFind(const ASET *set, const ELEMENT *element)
{
  int height, lower, half;
  int index = -1;
  height = set->cardinal - 1;
  lower = 0;
  while (lower <= height)
  {
    half = (height + lower) / 2;
    if (ElementEq(&set->element[half], element))
    {
      index = half;
      break;
    }
    else if (ElementGt(&set->element[half], element))
    {
      height = half - 1;
    }
    else if (ElementLt(&set->element[half], element))
    {
      lower = half + 1;
    }
  }
  return index;
} 

判断元素

int ASetExist(const ASET *set, const ELEMENT *element)
{
  int i, flag = 0;
  flag = ASetFind(set, element) != -1;
  return flag;
} 

添加元素

void ASetAppend(ASET *set, const ELEMENT *element)
{
  if(!ASetExist(set, element)) 
  {
    if (set->cardinal == set->size)
    {
      ASetResize(set, set->size + ASetIncrement);
    }
    int i;
    set->cardinal++;
    for (i = set->cardinal - 1; ElementGt(&set->element[i - 1], element) && i > 0; i--)
    // This step is cruial 
    // The conditions in the set are successfully avoided.
    // When there are on elements in the set, the garbage value cannot be compared
    // Move elements lager than element back to make room for element
    {
      set->element[i] = set->element[i - 1];
    }
    set->element[i] = *element;
  }
}

输出集合

void ASetOutput(const ASET *set)
{
  putchar('{');
  if (set->cardinal == 0)
  {
    putchar (' ');
  }
  int i;
  for (i = 0; i < set->cardinal; i++)
  {
        putchar (' ');
    ElementOutput(&set->element[i]);
    if (i != set->cardinal - 1)
    {
      putchar (',');
    }
  }
  if (set->cardinal)
  {
    putchar(' ');
  }
  putchar ('}');
}

删除元素

void ASetRemove(ASET *set, const ELEMENT *element)
{
  int k = 0;
    for (int i = 0; i < set->cardinal; i++)
    {
        if (ElementEq(&set->element[i], element))
        {
            k++;
        }
        else if (k)
        {
            set->element[i - k] = set->element[i];
        }
    }
    set->cardinal -= k;
}

清空集合

void ASetClear(ASET *set)
{
  set->cardinal = 0;
}

输入集合

/* Input set*/
void ASetInput(ASET *set)
{
  scanf (" {");
  char x;
  ELEMENT element;
  ASetClear (set);
  while (scanf (" %c", &x), x != '}')
  {
    ungetc(x, stdin);
    if (set->cardinal)
    {
      scanf (" ,"); 
    }
    if (set->cardinal == set->size)
    {
      ASetResize(set, set->size + ASetIncrement);
    }
    ElementInput(&element);
    ASetAppend(set, &element);
  }
}

判断空集

int ASetEmpty(const ASET *set)
{
  return set->cardinal == 0; 
} 

集合基数

int ASetCardinal(const ASET *set)
{
  return set->cardinal; 
} 

测试程序(main.c)

#include <stdio.h>
#include <ctype.h>
#include "ASet.h"
int main()
{
  ELEMENT element;
    ASET set;
    ASetCreate(&set);
  char choice;
  do
  {
    printf("E-判空 D-基数 A-添加 R-删除 C-清空 I-输入 O-输出 X-元素 Q-退出 > ");
    scanf(" %c", &choice);
    choice = toupper(choice);
    switch (choice)
    {
      case 'E':
        puts(ASetEmpty(&set) ? "空集" : "非空集"); 
        break;
      case 'D':
        printf("基数: %d\n", ASetCardinal(&set)); 
        break;
      case 'A':
        printf("元素: ");
        ElementInput(&element);
            ASetAppend(&set, &element);
        break;
      case 'R':
        printf("元素: ");
        ElementInput(&element);
        ASetRemove(&set, &element); 
        break;
      case 'C':
        ASetClear(&set); 
        break;  
      case 'I':
        printf("集合: ");
        ASetInput(&set);
        break;  
      case 'O':
        printf("集合: ");
        ASetOutput(&set);
        putchar('\n');
        break;
      case 'X':
                printf("元素: ");
        ElementInput(&element);
        puts(ASetExist(&set, &element) ? "存在" : "不存在");
        break;
      case 'Q':
        break;
      default:
        puts("不正确的选项!");
    }
  }
  while(choice != 'Q');
  ASetDestroy(&set);
  return 0;
}

运行结果:

E-判空 D-基数 A-添加 R-删除 C-清空 I-输入 O-输出 X-元素 Q-退出 > t
不正确的选项!
E-判空 D-基数 A-添加 R-删除 C-清空 I-输入 O-输出 X-元素 Q-退出 > E
空集
E-判空 D-基数 A-添加 R-删除 C-清空 I-输入 O-输出 X-元素 Q-退出 > d
基数: 0
E-判空 D-基数 A-添加 R-删除 C-清空 I-输入 O-输出 X-元素 Q-退出 > I
集合: { 31, 25, 16, 87, 49, 25, 87 }
E-判空 D-基数 A-添加 R-删除 C-清空 I-输入 O-输出 X-元素 Q-退出 > o
集合: { 16, 25, 31, 49, 87 }
E-判空 D-基数 A-添加 R-删除 C-清空 I-输入 O-输出 X-元素 Q-退出 > A
元素: 54
E-判空 D-基数 A-添加 R-删除 C-清空 I-输入 O-输出 X-元素 Q-退出 > a
元素: 25
E-判空 D-基数 A-添加 R-删除 C-清空 I-输入 O-输出 X-元素 Q-退出 > O
集合: { 16, 25, 31, 49, 54, 87 }
E-判空 D-基数 A-添加 R-删除 C-清空 I-输入 O-输出 X-元素 Q-退出 > r
元素: 49
E-判空 D-基数 A-添加 R-删除 C-清空 I-输入 O-输出 X-元素 Q-退出 > R
元素: 18
E-判空 D-基数 A-添加 R-删除 C-清空 I-输入 O-输出 X-元素 Q-退出 > o
集合: { 16, 25, 31, 54, 87 }
E-判空 D-基数 A-添加 R-删除 C-清空 I-输入 O-输出 X-元素 Q-退出 > E
非空集
E-判空 D-基数 A-添加 R-删除 C-清空 I-输入 O-输出 X-元素 Q-退出 > d
基数: 5
E-判空 D-基数 A-添加 R-删除 C-清空 I-输入 O-输出 X-元素 Q-退出 > X
元素: 31
存在
E-判空 D-基数 A-添加 R-删除 C-清空 I-输入 O-输出 X-元素 Q-退出 > x
元素: 32
不存在
E-判空 D-基数 A-添加 R-删除 C-清空 I-输入 O-输出 X-元素 Q-退出 > C
E-判空 D-基数 A-添加 R-删除 C-清空 I-输入 O-输出 X-元素 Q-退出 > o
集合: { }
E-判空 D-基数 A-添加 R-删除 C-清空 I-输入 O-输出 X-元素 Q-退出 > e
空集
E-判空 D-基数 A-添加 R-删除 C-清空 I-输入 O-输出 X-元素 Q-退出 > D
基数: 0
E-判空 D-基数 A-添加 R-删除 C-清空 I-输入 O-输出 X-元素 Q-退出 > a
元素: 18
E-判空 D-基数 A-添加 R-删除 C-清空 I-输入 O-输出 X-元素 Q-退出 > A
元素: 15
E-判空 D-基数 A-添加 R-删除 C-清空 I-输入 O-输出 X-元素 Q-退出 > a
元素: 37
E-判空 D-基数 A-添加 R-删除 C-清空 I-输入 O-输出 X-元素 Q-退出 > O
集合: { 15, 18, 37 }
E-判空 D-基数 A-添加 R-删除 C-清空 I-输入 O-输出 X-元素 Q-退出 > i
集合: { }
E-判空 D-基数 A-添加 R-删除 C-清空 I-输入 O-输出 X-元素 Q-退出 > O
集合: { }
E-判空 D-基数 A-添加 R-删除 C-清空 I-输入 O-输出 X-元素 Q-退出 > q
相关文章
|
6月前
|
存储 算法 程序员
【数据结构】C语言实现顺序表万字详解(附完整运行代码)
【数据结构】C语言实现顺序表万字详解(附完整运行代码)
161 0
|
20天前
|
存储 C语言
【数据结构】顺序表(c语言实现)(附源码)
本文介绍了线性表和顺序表的基本概念及其实现。线性表是一种有限序列,常见的线性表有顺序表、链表、栈、队列等。顺序表是一种基于连续内存地址存储数据的数据结构,其底层逻辑是数组。文章详细讲解了静态顺序表和动态顺序表的区别,并重点介绍了动态顺序表的实现,包括初始化、销毁、打印、增删查改等操作。最后,文章总结了顺序表的时间复杂度和局限性,并预告了后续关于链表的内容。
50 3
|
1月前
|
存储 C语言
探索C语言数据结构:利用顺序表完成通讯录的实现
本文介绍了如何使用C语言中的顺序表数据结构实现一个简单的通讯录,包括初始化、添加、删除、查找和保存联系人信息的操作,以及自定义结构体用于存储联系人详细信息。
19 2
|
1月前
|
C语言
链式顺序表实现(C语言描述)
本文介绍了如何在C语言中实现链式顺序表,包括数据结构的定义、节点的创建、数据的插入和删除以及链表的打印和销毁。
38 2
|
1月前
|
C语言
顺序表数组法构建(C语言描述)
如何使用C语言通过数组方法构建有序顺序表,包括顺序表的创建、插入、删除和打印等。
18 2
|
2月前
|
存储 C语言 C++
数据结构基础详解(C语言) 顺序表:顺序表静态分配和动态分配增删改查基本操作的基本介绍及c语言代码实现
本文介绍了顺序表的定义及其在C/C++中的实现方法。顺序表通过连续存储空间实现线性表,使逻辑上相邻的元素在物理位置上也相邻。文章详细描述了静态分配与动态分配两种方式下的顺序表定义、初始化、插入、删除、查找等基本操作,并提供了具体代码示例。静态分配方式下顺序表的长度固定,而动态分配则可根据需求调整大小。此外,还总结了顺序表的优点,如随机访问效率高、存储密度大,以及缺点,如扩展不便和插入删除操作成本高等特点。
196 5
|
2月前
|
存储 算法 C语言
C语言手撕数据结构代码_顺序表_静态存储_动态存储
本文介绍了基于静态和动态存储的顺序表操作实现,涵盖创建、删除、插入、合并、求交集与差集、逆置及循环移动等常见操作。通过详细的C语言代码示例,展示了如何高效地处理顺序表数据结构的各种问题。
|
5月前
|
存储 C语言
数据结构——顺序表(C语言版)
数据结构——顺序表(C语言版)
64 5
|
6月前
|
存储 C语言
C语言实验-动态顺序表实现简易通讯录(二)
在这个C语言实验中,你将实现一个简单的通讯录,它使用动态顺序表来存储联系人信息。
51 2
|
6月前
|
存储 C语言
数据结构——顺序表(C语言)
数据结构——顺序表(C语言)