記事ディレクトリ
1はじめに
前回の記事では主に、線形テーブルの概念、特性、構成、およびアプリケーションシナリオについて説明しました。この記事では、シーケンステーブルの挿入、削除、検索操作とC言語の実現について説明します。
2シーケンステーブルの挿入
シーケンステーブルの挿入時間の複雑さはO(n)です。シーケンステーブルの挿入には3つのタイプがあります。挿入タイプが異なるのは、主に要素コレクションの移動操作が異なるため、つまり効率が異なるためです。
- ヘッダー挿入、既存のすべての要素コレクションを右に移動、挿入効率が最も低い
- テーブルの最後に挿入し、既存の要素セットの一部を右に移動します。挿入効率は2番目です。
- テーブルの真ん中に挿入、既存の要素コレクションを移動する必要がなく、最高の挿入効率
シーケンステーブルの挿入手順:
[1]ターゲットの場所へのトラバース
[2]セット要素をターゲット位置から右に移動します
[3]要素を目的の位置に挿入します
C言語の実装:
int insert_sequence_list_node(sequence_list_t *list, list_node_type_t *value, int pos)
{
int i = 0;
if ((list==NULL) || (value==NULL))
{
return -1;
}
if (pos > list->capacity) /* 插入位置大于表长度 */
{
return -1;
}
if (list->occupy == list->capacity) /* 表已满 */
{
return -1;
}
pos = pos > list->occupy ? list->occupy : pos; /* 插入位置大于当前表占用长度 */
for (i=list->occupy; i>pos; i--)
{
list->data[i] = list->data[i-1];
}
memcpy(&list->data[pos], value, sizeof(list_node_type_t));
list->occupy++;
return 0;
}
3シーケンステーブルの削除
シーケンステーブルの削除と挿入は逆のプロセスで、挿入のタイプに応じて3種類の削除があります。
- ヘッダーを削除し、既存のすべての要素コレクションを左に移動します。削除効率は最低です
- テーブルの最後を削除し、既存の要素セットの一部を左に移動し、次に効率を削除します
- テーブルの中央で削除します。既存の要素コレクションを移動する必要はなく、最も効率的な削除です。
シーケンステーブルの削除手順:
[1]ターゲットの場所へのトラバース
[2]ターゲットの場所要素を削除します
[3]セット要素をターゲット位置から左に移動します
C言語の実装:
int delete_sequence_list_node(sequence_list_t *list, int pos)
{
list_node_type_t *node = NULL;
int i = 0;
if (list == NULL)
{
return -1;
}
if (pos > list->occupy)
{
return -1;
}
node = get_sequence_list_node(list, pos);
if (node != NULL)
{
for(i=pos; i<(list->occupy-1); i++)
{
list->data[i] = list->data[i+1];
}
list->occupy--;
return 0;
}
return -1;
}
4シーケンステーブルのルックアップ
シーケンステーブルの検索時間の複雑さはO(1)であり、インデックス(添え字)値に従って検索するだけでよく、検索効率は非常に高くなります。
C言語の実装:
list_node_type_t *get_sequence_list_node(sequence_list_t *list, int pos)
{
if (list == NULL)
{
return NULL;
}
if (0 == list->occupy)
{
return NULL;
}
if((pos>=0) && (pos<list->occupy))
{
return (list_node_type_t*)&list->data[pos];
}
}
5例
- シーケンステーブルを実装する
- シーケンステーブルの作成、挿入、削除、検索、破棄の操作インターフェイスを提供
#include <stdio.h>
#include <string.h>
#include <malloc.h>
typedef int list_node_type_t;
typedef struct _sequence_list
{
int capacity;
int occupy;
list_node_type_t *data;
}sequence_list_t;
sequence_list_t* create_sequence_list(int capacity, list_node_type_t node)
{
sequence_list_t* list = NULL;
if (capacity >= 0)
{
list = (sequence_list_t*)malloc(sizeof(sequence_list_t) + sizeof(list_node_type_t) * capacity);
}
if (list != NULL)
{
list->capacity = capacity;
list->occupy = 0;
list->data= (int*)(list + 1);
}
return list;
}
int destory_sequence_list(sequence_list_t *list)
{
if (list == NULL)
{
return -1;
}
free(list);
list = NULL;
return 0;
}
int get_sequence_list_capacity(sequence_list_t *list)
{
if (list == NULL)
{
return 0;
}
return list->capacity;
}
int get_sequence_list_occupy(sequence_list_t *list)
{
if (list == NULL)
{
return 0;
}
return list->occupy;
}
int clear_sequence_list(sequence_list_t *list)
{
if (list == NULL)
{
return -1;
}
list->occupy = 0;
return 0;
}
int insert_sequence_list_node(sequence_list_t *list, list_node_type_t *value, int pos)
{
int i = 0;
if ((list==NULL) || (value==NULL))
{
return -1;
}
if (pos > list->capacity) /* 插入位置大于表长度 */
{
return -1;
}
if (list->occupy == list->capacity) /* 表已满 */
{
return -1;
}
pos = pos > list->occupy ? list->occupy : pos; /* 插入位置大于当前表占用长度 */
for (i=list->occupy; i>pos; i--)
{
list->data[i] = list->data[i-1];
}
memcpy(&list->data[pos], value, sizeof(list_node_type_t));
list->occupy++;
return 0;
}
list_node_type_t *get_sequence_list_node(sequence_list_t *list, int pos)
{
if (list == NULL)
{
return NULL;
}
if (0 == list->occupy)
{
return NULL;
}
if((pos>=0) && (pos<list->occupy))
{
return (list_node_type_t*)&list->data[pos];
}
}
int delete_sequence_list_node(sequence_list_t *list, int pos)
{
list_node_type_t *node = NULL;
int i = 0;
if (list == NULL)
{
return -1;
}
if (pos > list->occupy)
{
return -1;
}
node = get_sequence_list_node(list, pos);
if (node != NULL)
{
for(i=pos; i<(list->occupy-1); i++)
{
list->data[i] = list->data[i+1];
}
list->occupy--;
return 0;
}
return -1;
}
int main(int argc, char *argv[])
{
sequence_list_t *seqlist = NULL;
list_node_type_t node;
list_node_type_t *ptemp;
int i;
/* 创建顺序表 */
seqlist = create_sequence_list(10, node);
/* 插入操作 */
node = 0;
insert_sequence_list_node(seqlist, &node, 0);
node = 1;
insert_sequence_list_node(seqlist, &node, 1);
node = 3;
insert_sequence_list_node(seqlist, &node, 2);
node = 5;
insert_sequence_list_node(seqlist, &node, 1);
printf("sequence list capacity:[%d]\n", seqlist->capacity);
printf("sequence list occupy:[%d]\n", seqlist->occupy);
for(i=0; i<get_sequence_list_occupy(seqlist); i++)
{
ptemp = get_sequence_list_node(seqlist, i);
printf("sequence list node[%d]=%d\n", i, *ptemp);
}
destory_sequence_list(seqlist); /* 销毁线性表 */
}
コンパイルして実行
- Ubuntu16.04での実行結果
acuity@ubuntu:/mnt/hgfs/LSW/STHB/temp$ gcc list.c -o list
acuity@ubuntu:/mnt/hgfs/LSW/STHB/temp$ ./list
sequence list capacity:[10]
sequence list occupy:[4]
sequence list node[0]=0
sequence list node[1]=5
sequence list node[2]=1
sequence list node[3]=3