C语言顺序表实现

73 阅读2分钟
  • seq_list.h
#ifndef __SEQ_LIST_H_
#define __SEQ_LIST_H_

#define INCREMENT 10


typedef int ElementType;

typedef struct {
  ElementType *data;
  int size;
  int capacity;
} SeqList;


/* 创建顺序表,成功:顺序表地址,失败:NULL */
SeqList* SeqList_Create(int capacity);

/* 销毁顺序表 */
void SeqList_Destroy(SeqList *list);

/* 插入元素,下标从0开始,成功返回1,失败返回0 */
int SeqList_Insert(SeqList *list, int pos, ElementType data);

/* 删除元素,下标从0开始,成功返回1,失败返回0 */
int SeqList_Delete(SeqList *list, int pos, ElementType *data);

/* 获取元素,下标从0开始,成功返回1,失败返回0 */
int SeqList_Get(SeqList *list, int pos, ElementType *data);

/* 遍历元素,顺序遍历顺序表 */
void SeqList_Traverse(SeqList *list, void (*handle)(ElementType));

#endif
  • seq_list.c
#include "seq_list.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>


/* 创建顺序表,成功:顺序表地址,失败:NULL */
SeqList* SeqList_Create(int capacity)
{
  SeqList *list;

  list = (SeqList*) malloc(sizeof(SeqList));

  if (NULL == list)
  {
    perror("SeqList_Create failed!");
    return NULL;
  }

  list->data = (ElementType *) malloc(capacity * sizeof(ElementType));

  if (NULL == list->data)
  {
    free(list);
    perror("SeqList_Create failed!");
    return NULL;
  }

  list->capacity = capacity;

  list->size = 0;

  return list;
}

/* 销毁顺序表 */
void SeqList_Destroy(SeqList *list)
{
  if (NULL == list)
    return;

  if (NULL != list->data)
    free(list->data);

  free(list);
}

/* 插入元素,下标从0开始,成功返回1,失败返回0 */
int SeqList_Insert(SeqList *list, int pos, ElementType data)
{
  ElementType *newData;

  if (NULL == list)
    return 0;

  if (list->size == list->capacity)
  {
    newData = realloc(list->data, (list->capacity + INCREMENT) * sizeof(ElementType));

    if (NULL == newData)
    {
      perror("realloc failed!");
      return 0;
    }

    list->data = newData;
    list->capacity += INCREMENT;
  }

  if (pos < 0)
    pos = 0;

  if (pos > list->size)
    pos = list->size;

  memmove(list->data + pos + 1, list->data + pos, (list->size - pos) * sizeof(ElementType));

  list->data[pos] = data;

  list->size++;

  return 1;
}

/* 删除元素,下标从0开始,成功返回1,失败返回0 */
int SeqList_Delete(SeqList *list, int pos, ElementType *data)
{
  ElementType *newData;
  int freeSize;
  int newCapacity;

  if (NULL == list)
    return 0;

  if (pos < 0)
    return 0;

  if (pos >= list->size)
    return 0;

  if (NULL != data)
    *data = list->data[pos];

  memmove(list->data + pos, list->data + pos + 1, (list->size - pos - 1) * sizeof(ElementType));

  list->size--;

  // 动态缩容,当空闲空间大于等于元素占用空间时,减少二分之一空闲空间
  freeSize = list->capacity - list->size;
  if (freeSize >= list->size && list->capacity > 20)
  {
    newCapacity = list->capacity - freeSize / 2;
    newData = realloc(list->data, newCapacity * sizeof(ElementType));

    if (NULL == newData)
    {
      perror("realloc failed!");
      return 0;
    }

    list->data = newData;
    list->capacity = newCapacity;
  }

  return 1;
}

/* 获取元素,下标从0开始,成功返回1,失败返回0 */
int SeqList_Get(SeqList *list, int pos, ElementType *data)
{
  if (NULL == list)
    return 0;

  if (pos < 0)
    return 0;

  if (pos >= list->size)
    return 0;

  *data = list->data[pos];

  return 1;
}

/* 遍历元素,顺序遍历顺序表 */
void SeqList_Traverse(SeqList *list, void (*handle)(ElementType))
{
  int i;

  if (NULL == list)
    return;

  for (i = 0; i < list->size; i++)
  {
    (*handle)(list->data[i]);
  }
}
  • seq_list_test.c
#include "seq_list.h"
#include <stdio.h>
#include <assert.h>

#define NUM 100

void print(ElementType data)
{
  printf("%d ", data);
}

int main(int argc, char **argv)
{
  ElementType data;
  int i;

  SeqList *list = SeqList_Create(10);

  if (NULL == list)
    return -1;

  printf("capacity: %d, size: %d\n", list->capacity, list->size);

  // 插入数据
  for (i = 0; i < NUM; i++)
  {
    SeqList_Insert(list, i, i);
    printf("capacity: %d, size: %d\n", list->capacity, list->size);
  }

  for (i = 0; i < NUM; i++)
  {
    SeqList_Get(list, i, &data);

    assert(data == i);
  }

  SeqList_Traverse(list, print);

  printf("\n");

  for (i = 0; i < NUM; i++)
  {
    SeqList_Delete(list, 0, &data);

    printf("capacity: %d, size: %d, data: %d\n", list->capacity, list->size, data);

    assert(i == data);

    assert(list->size == NUM - i - 1);
  }

  printf("\n");

  return 0;
}