栈的设计与实现及应用
一、目的和要求:
(1)正确定义栈(顺序栈或链栈);
(2)掌握栈基本操作实现方法;
(3)能正确分析算法的时间复杂度;
(3)采用栈解决实际问题。
二、实验原理及内容:
(1)定义栈(顺序栈或链栈);
(2)栈基本操作实现方法;
(3)采用栈解决实际问题(数制转换)。
三、实验步骤:(以顺序栈为例实现,也可以自行采用链栈实现)
(1)定义顺序栈;
(2)顺序栈基本操作实现方法;
(3)采用栈解决数制转换问题。
四、实验过程
1、工程结构如下图所示:
2、栈接口定义:IStack.java
public interface IStack<E> {
E push(E item); //入栈
E pop(); //出栈
E peek(); //取栈顶元素
int size();//返回栈中元素的个数
boolean empty();//判断栈是否为空
void clear(); //清空栈
}
3、顺序栈定义及基本操作实现: SeqStack.java
import java.lang.reflect.Array;
import java.lang.reflect.Array;
public class SeqStack<E> implements IStack<E> {
private int maxsize; // 顺序栈的容量
private E[]data; // 数组,用于存储顺序栈中的数据元素
private int top; // 指示顺序栈的栈顶
// 初始化栈
@SuppressWarnings("unchecked")
public SeqStack(Class<E> type,int size) {
data = (E[]) Array.newInstance(type, size);
this.maxsize = size;
top = 0;
}
// 入栈操作
public E push(E item) {
if (isFull()) {
data[top] = item;
top++;
return item;
} else
return null;
}
// 出栈操作
public E pop() {
if (!empty()) {
E temp = data[top - 1];
top--;
return temp;
} else {
return null;
}
}
// 获取栈顶数据元素
public E peek() {
if (!empty()) {
E temp = data[top - 1];
return temp;
} else {
return null;
}
}
// 求栈的长度
public int size() {
returntop;
}
// 判断顺序栈是否为空
public boolean empty() {
if (this.top == 0)
return true;
return false;
}
// 判断顺序栈是否为满
public boolean isFull() {
if (this.maxsize ==top)
return false;
return true;
}
// 清空栈
public void clear() {
this.top = 0;
}
}
4、链栈结点的定义:StackNode.java
public class StackNode<E> {
private Edata; // 数据域
private StackNode<E>next; // 引用域
//构造函数
public StackNode(){
}
public StackNode(E data) {
this.data = data;
}
public StackNode(E data, StackNode<E> next) {
super();
this.data = data;
this.next = next;
}
//数据域get属性
public E getData() {
return data;
}
//数据域set属性
public void setData(E data) {
this.data = data;
}
//引用域get属性
public StackNode<E> getNext() {
return next;
}
//引用域get属性
public void setNext(StackNode<E> next) {
this.next = next;
}
}
5、链栈定义及基本操作实现:LinkStack.java
public class LinkStack<E> implements IStack<E> {
private StackNode<E>top; // 栈顶指示器
private int size; // 栈中结点的个数
public StackNode<E> getTop() {
returntop;
}
public void setTop(StackNode<E> top) {
this.top = top;
}
public int getSize() {
returnsize;
}
public void setSize(int size) {
this.size = size;
}
// 初始化链栈
public LinkStack() {
top =null;
size = 0;
}
// 入栈操作
public E push(E item) {
StackNode<E> i = new StackNode<E>(item);
i.setNext(top);
top = i;
size++;
return item;
}
// 出栈操作
public E pop() {
E i = null;
if (!empty()) {
i = top.getData();
top =top.getNext();
size--;
}
return i;
}
// 获取栈顶数据元素
public E peek() {
if (!empty())
returntop.getData();
return null;
}
// 求栈的长度
public int size() {
returnsize;
}
// 判断顺序栈是否为空
public boolean empty() {
if (top ==null)
return true;
return false;
}
// 清空栈
public void clear() {
top =null;
}
}
6、栈的测试
public class TestStack {
public static void main(String[] args) {
int[] data={23,45,3,7,6,945};
//IStack<Integer> stack=new SeqStack<Integer>(Integer.class,data.length);
IStack<Integer> stack=new LinkStack<Integer>();
//入栈操作
System.out.println("*******入栈操作*******");
for(int i=0; i<data.length;i++){
stack.push(data[i]);
System.out.println(data[i]+"入栈");
}
int size=stack.size();
//出栈操作
System.out.println("*******出栈操作*******");
for(int i=1; i<size;i++){
System.out.println(stack.pop()+"出栈 ");
}
}
}
7、使用栈解决进制转换问题
import java.util.Scanner;
/**
* 键盘输十进制数,输出转成的其它进制结果
* 先输入用例个数n
* 接下来n行,每行两个数,分别表示要转换的数及对应的进制(只能转成十六进制以内的进制)
* @author Administrator
*/
public class Numberconvert {
public static void main(String[] args) {
Character ch[]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
Scanner sc = new Scanner(System.in);
int n; //用例数
int m; //想转换的数
int k; //想转换成的目标进制
int t;
IStack<Character> stack = new SeqStack<Character>(Character.class,100);
//IStack<Character> stack=new LinkStack<Character>();
n = sc.nextInt();
for(int i=0;i<n;i++){
m = sc.nextInt();
k = sc.nextInt();
if(m==0) System.out.println(0);
else
{
stack.clear();
//请在此补充代码,实现余数入栈
while(m>0)
{
stack.push(ch[m%k]);
m = m/k;
}
while(!stack.empty()){
System.out.print(stack.pop());
}
System.out.println();
}
}
}
}