データ構造レビュー-シーケンステーブル操作とC言語実装の詳細な説明


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

おすすめ

転載: blog.csdn.net/qq_20553613/article/details/108025910