数据结构回顾——顺序表操作详解及C语言实现


1 前言

  上一篇文章主要描述线性表的概念、特点、组成和适用场景。本文描述顺序表的插入、删除、查找操作以及C语言的实现。


2 顺序表插入

  顺序表插入时间复杂度为O(n),顺序表插入类型有三种,不同的插入类型主要是元素集合移动操作不同,即是效率不同。

  • 表头插入,将已有的元素集合全部右移,插入效率最低
  • 表尾插入,将已有的元素集合一部分右移,插入效率次之
  • 表中间插入,不需移动已存在元素集合,插入效率最高

 顺序表插入步骤:

【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 顺序表删除

  顺序表删除与插入是一个相反的的过程,删除类型有三种,与插入类型对应。

  • 表头删除,将已有的元素集合全部左移,删除效率最低
  • 表尾删除,将已有的元素集合一部分左移,删除效率次之
  • 表中间删除,不需移动已存在元素集合,删除效率最高

 顺序表删除步骤:

【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
今日推荐