1.1 线性表 - 顺序存储结构

1. 顺序存储结构的定义

在这里插入图片描述

typedef struct seqence_list{
	datatype *data;
	int last;
	int size;
}sqlist;

2 主要操作的实现

2.1 初始化

sqlist *init_sl(int size){
	sqlist *sl = calloc(1, sizeof(sqlist)); // 分配顺序表
	
	if( sl!=NULL){
		sl->data = calloc(size, sizeof(datatype)); // 分配结构空间
		if( sl->data == NULL){ // 分配失败,退出
			free(sl);
			return NULL;
		}
		sl->last = -1;
		sl->size = size;
	}
	
	return sl;
}

2.2 判断顺序表是否满了

bool is_full(sqlist *sl) {
	return sl->last == sl->size-1;
}

2.3 判断顺序表是否空的

bool is_empty(sqlist *sl) {
	return sl->last == -1;
}

2.4 顺序表插入节点

  • 输入: int n(插入的数据),sqlist *sl(顺序表)
  • 输入:布尔型(判断插入是否成功)
    在这里插入图片描述
bool insert_node( int n, sqlist *sl){
	if (is_full(sl))
		return false;
	
	// 找到n应该插入的位置 
	int pos; // 插入位置 
	for (pos=0; pos<=sl->last; pos++){
		if(n<sl->data[pos]){
			break;
		}
	}
	
	// 成片地移动数据
	int i;
	for(i=sl->last; i>=pos; i--) {
		sl->data[i+1] = sl->data[i];
	}
	
	// 将n放入pos
	sl->data[pos] = n;
	
	// 更新last
	sl->last++;	
	return true;
}

2.5 顺序表删除结点

  • 输入: int n(删除的数据),sqlist *sl(顺序表)
  • 输入:布尔型(判断删除是否成功)
    在这里插入图片描述
bool remove_node( int n, sqlist *sl) {
	if( is_empty(sl) ){
		return false;
	}
	
	// 查找应该删除的位置
	int pos;
	for (pos=0; pos<=sl->last; pos++) {
		if (n == sl->data[pos]){
			break;
		}
	}
	
	if ( pos==sl->last+1){
		return false;
	}
	
	// 成片移动数据
	int i;
	for ( i=pos; i<sl->last; i++){
		sl->data[i] = sl->data[i+1];
	}
	
	sl->last--;
	return true;
}

插入或删除一个数据元素时,其时间主要耗费在移动元素上,而移动元素的个数取决于插入或删除元素的位置,所以它们的时间复杂度T=O(n)。

2.6 销毁节点

void destroy_list(sqlist *sl) {
	free(sl->data);
	free(sl);
}

3 顺序存储结构的特点

  • 逻辑关系上相邻的两个元素在物理位置上也相邻
  • 可以随机存取表中任一元素,它的存储位置可用一个简单、直观的公式来表示
  • 最大的缺点就是插入和删除时需要移动大量的元素,这显然需要耗费时间。

4 练习题目

用顺序存储的方式处理正整数:输入正整数表示插入数据(比如输入3表示插入3),输入负整数表示删除数据,输入0表示退出程序。并要求:插入和删除的过程中保持该表递增有序。
在这里插入图片描述

#include "common.h"

#ifndef SL_NODE_TYPE
#define SL_NODE_TYPE int // 默认的节点类型是int
#endif

typedef SL_NODE_TYPE datatype;

typedef struct seqence_list{
	datatype *data;
	int last;
	int size;
}sqlist;

// 初始化函数 
sqlist *init_sl(int size){
	sqlist *sl = calloc(1, sizeof(sqlist)); // 分配顺序表
	
	if( sl!=NULL){
		sl->data = calloc(size, sizeof(datatype)); // 分配结构空间
		if( sl->data == NULL){ // 分配失败,退出
			free(sl);
			return NULL;
		}
		sl->last = -1;
		sl->size = size;
	}
	
	return sl;
}

// 判断表是否满了
bool is_full(sqlist *sl) {
	return sl->last == sl->size-1;
}

// 判断表是否空的
bool is_empty(sqlist *sl) {
	return sl->last == -1;
}

// 
void show_list(sqlist *sl){
	if (is_empty(sl)){
		return;
	}
	
	int i;
	for(i=0; i<=sl->last; i++){
		printf("%d ", sl->data[i]);
	}
}

// 插入节点
bool insert_node( int n, sqlist *sl){
	if (is_full(sl))
		return false;
	
	// 找到n应该插入的位置 
	int pos; // 插入位置 
	for (pos=0; pos<=sl->last; pos++){
		if(n<sl->data[pos]){
			break;
		}
	}
	
	// 成片地移动数据
	int i;
	for(i=sl->last; i>=pos; i--) {
		sl->data[i+1] = sl->data[i];
	}
	
	// 将n放入pos
	sl->data[pos] = n;
	
	// 更新last
	sl->last++;	
	return true;
}

// 删除节点
bool remove_node( int n, sqlist *sl) {
	if( is_empty(sl) ){
		return false;
	}
	
	// 查找应该删除的位置
	int pos;
	for (pos=0; pos<=sl->last; pos++) {
		if (n == sl->data[pos]){
			break;
		}
	}
	
	if ( pos==sl->last+1){
		return false;
	}
	
	// 成片移动数据
	int i;
	for ( i=pos; i<sl->last; i++){
		sl->data[i] = sl->data[i+1];
	}
	
	sl->last--;
	return true;
}

// 销毁节点
void destroy_list(sqlist *sl) {
	free(sl->data);
	free(sl);
}


int main(void){
	// 1. 初始化一个空的顺序表
	sqlist *sl = init_sl(1000);
	if(sl == NULL){
		printf("初始化顺序表失败\n");
		exit(0);
	}
	
	// 2. 循环地放入、删除数据
	int n;
	while(1) {
		scanf("%d", &n);
		
		//出入节点
		if(n>0){ 
			if(insert_node(n, sl)) 
				show_list(sl); // 将顺序表中的所有元素列出来
			else
				printf("插入节点失败\n"); 
		}
		
		// 删除节点 
		if(n<0){
			if( remove_node(-n, sl) )
				show_list(sl); //
			else
				printf("无此节点\n");
		}
		
		// 退出
		if(n==0) {
			break;
		}
	}
	
//	// 3. 销毁顺序表
//	destroy_sl(sl) ;
	
	return 0;
}

代码引用常用头文件,如果报错可以参考另外一篇常用头文件 - common.h

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值