スタック(スタック)のチェーン実装の詳細な説明----線形構造

線形ストレージの線形テーブル操作は以前に学習されました。つまり、線形テーブルの順序、連鎖ストレージ、表現などの要素間の1対1の関係は、データ要素間の線形性の現れです。

線形テーブルに加えて、線形に格納されるデータ構造には、スタックとキュー、文字列、配列、および一般化されたテーブルが含まれます。

今日、私は主にデータ構造の中で非常に重要なデータ構造、つまり------>スタックをあなたと共有します

「スタック」を理解する方法は?

スタックは私たちの生活の中で広く使われています。たとえば、料理や料理に使用する料理は、通常、下から上に1つずつ配置する必要があり、上から使用する必要があります。次へ。使用するために取り出すもの。
また、これまで見てきたピストルのマガジンと同様に、マガジンを装填するときは、弾丸を上から下に1つずつ押す必要があり、弾丸が発射されると、下から上に1つずつ排出されます。待ってください、アートは人生から来ています、ハハ、人生にはスタックアプリケーションの例が多すぎるので、誰もが理解できます。

スタックの特性を要約すると、後入れ先出し(LIFO)です。
これに対応するのは、キューの特徴的な先入れ先出し(FIFO)です。

下から上に要素を追加する操作を---->プッシュ操作
と呼び、要素を上から外側に減らす操作を---->ポップ操作と呼びます。

スタックはスタックの一番上からしか操作できません。つまり、追加と削除は一番上からしか操作できないため、スタックを操作が制限された線形リストにします

教科書にはすでにスタックの順次実装があるので、擬似コードですが(実際にはそれを見るのに使用されていません、笑)、スタックのチェーン実装を実装し、参照用に提供しました。

最後に、私が自分で追加したものは、スタックの一番上から一番下まですべての要素を出力することによって実装されます(補助スタックを使用)。他の友人が他のアイデアを持っている場合は、コメントして議論してください〜

チェーンスタック構造の定義

単純なスタック要素の定義とチェーンスタックの定義

#include<stdio.h>
#include<stdlib.h>
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2

//定义栈内存储的元素Student 
struct Student{
    
    	
	int id;				//学生id 
	int age;			//学生年龄 
	Student *next;		//指向下一元素的指针 
};


//定义以链式存储的数据栈 
typedef struct Node{
    
    	
	Student *base;		//定义栈底指针,用于指向栈底元素 
	Student *top;		//定义栈顶指针,用于指向栈顶元素, 它们初始化均为NULL 
}*Stack;

すべてのメソッド宣言

int initStack(Stack &stack);						//初始化链表栈 
int clearStack(Stack &stack);						//清空栈内的所有数据 
int destroyStack(Stack &stack);						//销毁链表数据栈 
int stackEmpty(Stack &stack);						//判断链表栈是否为NULL 
int stackLength(Stack &stack);						//获取栈长的函数 
int getStackTop(Stack &stack, Student &student);		//获取栈顶元素 
int pushStack(Stack &stack, Student student);			//压栈操作,将一个元素压入栈中 
int popStack(Stack &stack, Student &student);			//出栈操作,将一个元素弹出栈,并以参数student返回 
void printStack(Stack &stack);						//以栈顶到栈底的形式输出栈内所有元素 
void stackTraverse(Stack &stack);					//以栈底到栈顶的形式输出栈内所有元素 

スタック操作を初期化する

スタックの初期化


//数据结构----初始化链式数据栈操作 
int initStack(Stack &stack)
{
    
    
	stack = (Node *)malloc(sizeof(Node));			//使用malloc函数动态为数据栈开辟空间 
	stack->base = NULL;					//栈底指针指向NULL 
	stack->top = NULL;					//栈顶指针指向NULL 
	
	return OK;					//返回建栈成功信息 
}

プッシュ操作

プッシュ操作は、関数によって渡されたパラメーターに従ってデータ要素をスタックにプッシュします


//数据结构----push压栈操作,将一个数据元素压入栈中 
int pushStack(Stack &stack, Student student)
{
    
    
	Student *student1 = (Student *)malloc(sizeof(Student));		//动态开辟一个元素空间 
	
	student1->id = student.id;				//信息收集,获取将压栈元素的id 
	student1->age = student.age;			//获取将压栈元素的age 
	
	if(stack->base == NULL)					//若栈底为NULL时,说明栈内还没有元素 
	{
    
    
		stack->base = student1;			//栈底指向该元素student1 
		stack->top = student1;			//栈顶指向该元素student1 
	}
	else									//否则 
	{
    
    
		stack->top->next = student1; 		//将元素student1压入栈中 
		stack->top = student1;				//栈顶指针指向新元素student1 
	}
	
	stack->top->next = NULL;		//设置下次待压入元素的地址暂为NULL(与链式线性表的增加元素有些许类似) 
	
	return OK;
}

ポップ操作

ポップ操作、スタックの最上位要素をポップし、ポップされた情報を保存して、関数パラメーターを介して返します


//数据结构----出栈操作,将栈顶元素进行弹出 
int popStack(Stack &stack, Student &student)
{
    
    
	Student *p = stack->base, *q;		//定义p指针暂时指向栈底元素 
	
	if(stackEmpty(stack)) return ERROR;		//若栈空则返回失败信息 
	
	if(stack->top == stack->base)		//若栈顶指针和栈底指针指向同一元素,表示栈内仅有一个元素 
	{
    
    
		student = *stack->top;			//以参数的形式保存栈顶元素并返回 
		free(stack->top);			//释放栈顶元素,进行出栈删除 
		stack->base = NULL;				 
		stack->top = NULL;			//栈底、顶指针再次指向NULL,代表暂无任何元素 
		return OK;					//返回成功信息 
	}
	
	while(p->next != stack->top)		//若栈内的元素 >= 2
	p = p->next;					//p指针从栈底循环上挪 ,直到p指向指向栈顶元素之下的元素 
	
	q = stack->top;					//q指针指向栈顶元素					
	student = *q;					//将栈顶元素赋值给参数student待返回 
	stack->top = p;						//栈顶指针下挪 
	stack->top->next = NULL;			//设置下次待压入元素的地址暂为NULL
	
	free(q);						//释放原栈顶指针 
	return OK;							//返回成功信息 
	
}

すべての要素を上から下に印刷します

補助スタックを使用して、スタックの一番上から一番下まですべての要素を出力します


//数据结构----自栈顶至栈底的方式输出所有元素 
void printStack(Stack &stack)
{
    
    
	int i = 0;
	Stack new_stack; 
	initStack(new_stack);		//定义一个新的栈,并且进行初始化 
	
	Student student;			//定义元素变量student 
	printf("自栈顶到栈底的数据元素排列:\n");
	
	
	//stack出栈顺序:			A、B、C、D、E	---->  结果:stack栈空 
	//同时new_stack压栈顺序: 	A、B、C、D、E	---->  结果:new_stack已保存原stack栈 
	 
	while(!(stackEmpty(stack)))		//若原栈不为NULL,重复循环 
	{
    
    
		popStack(stack, student);  				 //出栈操作 
		printf("id = %d, age = %d.\n", student.id, student.age);	//信息输出 
		pushStack(new_stack, student);			 //压栈操作 
		i++;							// 计数器累加 
	}
	printf("共有数据 %d 条.\n\n", i);		   	//输出结果的个数 
	stack = new_stack;							//进行栈复制,原栈已恢复! 
	return;						//返回 
}

すべての要素を下から上に印刷します

//数据结构----自栈底至栈顶的方式输出所有元素 
void stackTraverse(Stack &stack)
{
    
    
	int i = 0;
	Student *student = stack->base;					//定义随机变量指针student指向栈底元素 
	printf("自栈底到栈顶的数据元素排列:\n");
	while(student != NULL)							//循环遍历输出 
	{
    
    
		printf("id = %d, age = %d.\n", student->id, student->age);
		student = student->next;				//指针随栈进行上挪输出下一元素 
		i++;								//计数器累加 
	}
	printf("共有数据 %d 条.\n\n", i);		//输出累加数据 
	return;
}

スタックの最上位要素を取得します

チェーンスタックの最上位要素を取得します


//数据结构----获取栈顶元素 
int getStackTop(Stack &stack, Student &student)
{
    
    
	if(stack->top != NULL)					//若栈顶元素不为NULL 
	{
    
    
		student = *stack->top;				//将栈顶元素传递给参数变量 
		return OK;				//返回成功信息 
	}
	else return ERROR;			//否则返回失败信息 
}

チェーンスタックの長さを取得します

//数据结构----测试栈长函数 
int stackLength(Stack &stack)
{
    
    
	Student *student = stack->base;			//定义随机变量元素指向栈底元素 
	int i = 0;
	while(student != NULL)					//循环遍历统计 
	{
    
    
		student = student->next;			//不断指向栈上层元素 
		i++;					//计数器累加 
	}
	
	return i;					//返回长度 
}

スタックを破棄し、スタックをクリアし、スタックが空の操作であると判断します

//数据结构----销毁链式数据栈操作 
int destroyStack(Stack &stack)
{
    
    
	clearStack(stack);			//清空数据栈内的所有元素 
	free(stack);				//释放栈的地址空间内存 
	stack = NULL;				//设置栈指针为NULL,即销毁
	return OK;					//返回成功信息 
}


//数据结构----清理链式数据栈 
int clearStack(Stack &stack)
{
    
    
	Student student;						//定义临时元素变量Student 
	while(stack->base != NULL)				//当栈底指针不为NULL时,循环进行出栈操作 
	popStack(stack,student);			//元素出栈 
	
	if(stack->base == NULL) return OK;		//若栈底已为NULL,返回成功信息 
	else return ERROR;					//否则返回失败信息 
}



//数据结构----判断栈空函数 
int stackEmpty(Stack &stack)
{
    
    
	if(stack->base == NULL && stack->top == NULL)
		return TRUE;						//若栈底指针和栈顶指针指向NULL,返回true 
	else	
		return FALSE;						//否则返回false 
}

これらのメソッドのテストコードはここでは書きません。友達は自分で参照してコミュニケーションを取り、一緒に進歩することができます。最近、高度な数学やその他のコースも学んでいます。更新が少し遅いかもしれません。ハハ、次へチェーンキューの実装を準備します。

おすすめ

転載: blog.csdn.net/weixin_43479947/article/details/113447400