java数据结构及算法四

不同的数据结构和算法会有很明显的不同。数据结构要适合于程序中的数据类型。
栈和队列是通过定义接口的可执行的操作而定义的。例如栈可以是数组也可以是链表。
这种后进先出的数据结构在程序设计中十分有用,比如匹配源文件中的括号,对更为复杂的数据结构的算法也是有便利的帮助。许多微处理器也是基于堆栈的设计,当一个方法被调用,它的地址和参数被放入堆栈,当方法返回时他们又被弹出。像堆到一起的邮件,首先处理的数据时最上端的。堆栈的概念和实现堆栈的数据结构是有很大区别的。 
主要的操作:压栈、出栈、取值、取大小
// Stack.java
// demonstrates stacks
// to run this program: C>java StackApp
import java.io.*; // for I/O

class StackX
{
private int maxSize; // size of stack array
private double[] stackArray;
private int top; // top of stack
//-------------------------------------------------------------
-
public StackX(int s) // constructor
{
maxSize = s; // set array size
stackArray = new double[maxSize]; // create array
top = -1; // no items yet
}
//-------------------------------------------------------------
-
public void push(double j) // put item on top of stack
{
stackArray[++top] = j; // increment top, insert item
}
//-------------------------------------------------------------
-
public double pop() // take item from top of stack
{
return stackArray[top--]; // access item, decrement top
}
//-------------------------------------------------------------
-
public double peek() // peek at top of stack
{
return stackArray[top];
}
//-------------------------------------------------------------
-
public boolean isEmpty() // true if stack is empty
{
return (top == -1);
}
//-------------------------------------------------------------
-
public boolean isFull() // true if stack is full
{
return (top == maxSize-1);
}
//-------------------------------------------------------------
-
} // end class StackX

class StackApp
{
public static void main(String[] args)
{
StackX theStack = new StackX(10); // make new stack
theStack.push(20); // push items onto stack
theStack.push(40);
theStack.push(60);
theStack.push(80);
while( !theStack.isEmpty() ) // until it's empty,
{ // delete item from
stack
double value = theStack.pop();
System.out.print(value); // display it
System.out.print(" ");
} // end while
System.out.println("");
} // end main()
} // end class StackApp
一般堆栈都是内部检查越界错误,一个比较好的处理方式是内部发现例外,抛给堆栈的使用者。
堆栈的使用:
翻转单词
// reverse.java
// stack used to reverse a string
// to run this program: C>java ReverseApp
import java.io.*; // for I/O

class StackX
{
private int maxSize;
private char[] stackArray;
private int top;
//-------------------------------------------------------------
-
public StackX(int max) // constructor
{
maxSize = max;
stackArray = new char[maxSize];
top = -1;
}
//-------------------------------------------------------------
-
public void push(char j) // put item on top of stack
{
stackArray[++top] = j;
}
//-------------------------------------------------------------
-
public char pop() // take item from top of stack
{
return stackArray[top--];
}
//-------------------------------------------------------------
-
public char peek() // peek at top of stack
- 97 -
{
return stackArray[top];
}
//-------------------------------------------------------------
-
public boolean isEmpty() // true if stack is empty
{
return (top == -1);
}
//-------------------------------------------------------------
-
} // end class StackX

class Reverser
{
private String input; // input string
private String output; // output string
//-------------------------------------------------------------
-
public Reverser(String in) // constructor
{ input = in; }
//-------------------------------------------------------------
-
public String doRev() // reverse the string
{
int stackSize = input.length(); // get max stack size
StackX theStack = new StackX(stackSize); // make stack
for(int j=0; j<input.length(); j++)
{
char ch = input.charAt(j); // get a char from
input
theStack.push(ch); // push it
}
output = "";
while( !theStack.isEmpty() )
{
char ch = theStack.pop(); // pop a char,
output = output + ch; // append to output
}
return output;
} // end doRev()
//-------------------------------------------------------------
-
} // end class Reverser

- 98 -
class ReverseApp
{
public static void main(String[] args) throws IOException
{
String input, output;
while(true)
{
System.out.print("Enter a string: ");
System.out.flush();
input = getString(); // read a string from
kbd
if( input.equals("") ) // quit if [Enter]
break;
// make a Reverser
Reverser theReverser = new Reverser(input);
output = theReverser.doRev(); // use it
System.out.println("Reversed: " + output);
} // end while
} // end main()
//-------------------------------------------------------------
-
public static String getString() throws IOException
{
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(isr);
String s = br.readLine();
return s;
}
//-------------------------------------------------------------
-
} // end class ReverseApp
字符匹配:
Listing 4.3 The brackets.java Program
// brackets.java
// stacks used to check matching brackets
// to run this program: C>java BracketsApp
import java.io.*; // for I/O

class StackX
{
private int maxSize;
private char[] stackArray;
private int top;
//-------------------------------------------------------------
-
public StackX(int s) // constructor
{
maxSize = s;
stackArray = new char[maxSize];
top = -1;
}
//-------------------------------------------------------------
-
public void push(char j) // put item on top of stack
{
stackArray[++top] = j;
}
//-------------------------------------------------------------
-
- 101 -
public char pop() // take item from top of stack
{
return stackArray[top--];
}
//-------------------------------------------------------------
-
public char peek() // peek at top of stack
{
return stackArray[top];
}
//-------------------------------------------------------------
-
public boolean isEmpty() // true if stack is empty
{
return (top == -1);
}
//-------------------------------------------------------------
-
} // end class StackX

class BracketChecker
{
private String input; // input string
//-------------------------------------------------------------
-
public BracketChecker(String in) // constructor
{ input = in; }
//-------------------------------------------------------------
-
public void check()
{
int stackSize = input.length(); // get max stack
size
StackX theStack = new StackX(stackSize); // make stack
for(int j=0; j<input.length(); j++) // get chars in turn
{
char ch = input.charAt(j); // get char
switch(ch)
{
case '{': // opening symbols
case '[':
case '(':
theStack.push(ch); // push them
break;
case '}': // closing symbols
- 102 -
case ']':
case ')':
if( !theStack.isEmpty() ) // if stack not
empty,
{
char chx = theStack.pop(); // pop and check
if( (ch=='}' && chx!='{') ||
(ch==']' && chx!='[') ||
(ch==')' && chx!='(') )
System.out.println("Error: "+ch+" at "+j);
}
else // prematurely empty
System.out.println("Error: "+ch+" at "+j);
break;
default: // no action on other characters
break;
} // end switch
} // end for
// at this point, all characters have been processed
if( !theStack.isEmpty() )
System.out.println("Error: missing right delimiter");
} // end check()
//-------------------------------------------------------------
-
} // end class BracketChecker

class BracketsApp
{
public static void main(String[] args) throws IOException
{
String input;
while(true)
{
System.out.print(
"Enter string containing delimiters: ");
System.out.flush();
input = getString(); // read a string from kbd
if( input.equals("") ) // quit if [Enter]
break;
// make a BracketChecker
BracketChecker theChecker = new BracketChecker(input);
theChecker.check(); // check brackets
} // end while
} // end main()
//-------------------------------------------------------------
-
public static String getString() throws IOException
{
InputStreamReader isr = new InputStreamReader(System.in);
- 103 -
BufferedReader br = new BufferedReader(isr);
String s = br.readLine();
return s;
}
//-------------------------------------------------------------
-
} // end class BracketsApp
堆栈效率: 1
队列:
先进先出的操作方式,像影院门口的队伍,先排队的人先买到票。队列可作为图结构的搜索辅助,也被用于现实世界的模拟。基本操作有插入、弹出、取值、判空、判满。
环形对列:
避免队列未满而不能插入元素。从最后的索引在回到起始的索引值。
// Queue.java
// demonstrates queue
// to run this program: C>java QueueApp
import java.io.*; // for I/O

class Queue
{
private int maxSize;
private int[] queArray;
private int front;
private int rear;
private int nItems;
//-------------------------------------------------------------
-
public Queue(int s) // constructor
{
maxSize = s;
queArray = new int[maxSize];
front = 0;
rear = -1;
nItems = 0;
}
//-------------------------------------------------------------
-
public void insert(int j) // put item at rear of queue
{
if(rear == maxSize-1) // deal with wraparound
rear = -1;
queArray[++rear] = j; // increment rear and
insert
nItems++; // one more item
}
//-------------------------------------------------------------
-
public int remove() // take item from front of queue
{
int temp = queArray[front++]; // get value and incr front
if(front == maxSize) // deal with wraparound
front = 0;
nItems--; // one less item
return temp;
}
//-------------------------------------------------------------
-
public int peekFront() // peek at front of queue
{
- 109 -
return queArray[front];
}
//-------------------------------------------------------------
-
public boolean isEmpty() // true if queue is empty
{
return (nItems==0);
}
//-------------------------------------------------------------
-
public boolean isFull() // true if queue is full
{
return (nItems==maxSize);
}
//-------------------------------------------------------------
-
public int size() // number of items in queue
{
return nItems;
}
//-------------------------------------------------------------
-
} // end class Queue

class QueueApp
{
public static void main(String[] args)
{
Queue theQueue = new Queue(5); // queue holds 5 items
theQueue.insert(10); // insert 4 items
theQueue.insert(20);
theQueue.insert(30);
theQueue.insert(40);
theQueue.remove(); // remove 3 items
theQueue.remove(); // (10, 20, 30)
theQueue.remove();
theQueue.insert(50); // insert 4 more items
theQueue.insert(60); // (wraps around)
theQueue.insert(70);
theQueue.insert(80);
while( !theQueue.isEmpty() ) // remove and display
{ // all items
int n = theQueue.remove(); // (40, 50, 60, 70, 80)
System.out.print(n);
- 110 -
System.out.print(" ");
}
System.out.println("");
} // end main()
} // end class QueueApp
环形队列:
class Queue
{
private int maxSize;
private int[] queArray;
private int front;
private int rear;
//-------------------------------------------------------------
-
public Queue(int s) // constructor
{
maxSize = s+1; // array is 1 cell larger
queArray = new int[maxSize]; // than requested
front = 0;
rear = -1;
}
//-------------------------------------------------------------
-
public void insert(int j) // put item at rear of queue
{
if(rear == maxSize-1)
rear = -1;
queArray[++rear] = j;
}
//-------------------------------------------------------------
-
public int remove() // take item from front of queue
{
int temp = queArray[front++];
if(front == maxSize)
front = 0;
return temp;
}
//-------------------------------------------------------------
-
public int peek() // peek at front of queue
{
return queArray[front];
- 112 -
}
//-------------------------------------------------------------
-
public boolean isEmpty() // true if queue is empty
{
return ( rear+1==front || (front+maxSize-1==rear) );
}
//-------------------------------------------------------------
-
public boolean isFull() // true if queue is full
{
return ( rear+2==front || (front+maxSize-2==rear) );
}
//-------------------------------------------------------------
-
public int size() // (assumes queue not empty)
{
if(rear >= front) // contiguous sequence
return rear-front+1;
else // broken sequence
return (maxSize-front) + (rear+1);
}
//-------------------------------------------------------------
-
} // end class Queue
优先队列
队列元素按关键字优先级排列,如同邮件排列的先后顺序。
// priorityQ.java
// demonstrates priority queue
// to run this program: C>java PriorityQApp
import java.io.*; // for I/O
class PriorityQ
{
// array in sorted order, from max at 0 to min at size-1
private int maxSize;
private double[] queArray;
private int nItems;
//-------------------------------------------------------------
public PriorityQ(int s) // constructor
{
- 116 -
maxSize = s;
queArray = new double[maxSize];
nItems = 0;
}
//-------------------------------------------------------------
public void insert(double item) // insert item
{
int j;
if(nItems==0) // if no items,
queArray[nItems++] = item; // insert at 0
else // if any items,
{
for(j=nItems-1; j>=0; j--) // start at end,
{
if( item > queArray[j] ) // if new item
larger,
queArray[j+1] = queArray[j]; // shift upward
else // if smaller,
break; // done shifting
} // end for
queArray[j+1] = item; // insert it
nItems++;
} // end else (nItems > 0)
} // end insert()
//-------------------------------------------------------------
public double remove() // remove minimum item
{ return queArray[--nItems]; }
//-------------------------------------------------------------
public double peekMin() // peek at minimum item
{ return queArray[nItems-1]; }
//-------------------------------------------------------------
public boolean isEmpty() // true if queue is empty
{ return (nItems==0); }
//-------------------------------------------------------------
public boolean isFull() // true if queue is full
{ return (nItems == maxSize); }
//-------------------------------------------------------------
} // end class PriorityQ
class PriorityQApp
{
public static void main(String[] args) throws IOException
{ PriorityQ thePQ = new PriorityQ(5);
- 117 -
thePQ.insert(30);
thePQ.insert(50);
thePQ.insert(10);
thePQ.insert(40);
thePQ.insert(20);
while( !thePQ.isEmpty() )
{
double item = thePQ.remove();
System.out.print(item + " "); // 10, 20, 30, 40, 50
} // end while
System.out.println("");
} // end main()
//-------------------------------------------------------------
} // end class PriorityQApp
匹配算术表达式
非其它章节的先决条件,在一般的程序设计中也不常见,只是有助于理解堆栈的使用。
Infix 中缀表达式, postfix 后缀表达式 ( 逆波兰式 ) prefix 前缀表达 ( 较少使用 )
Listing 4.7 The infix.java Program
// infix.java
// converts infix arithmetic expressions to postfix
// to run this program: C>java InfixApp
import java.io.*; // for I/O
- 131 -
class StackX
{
private int maxSize;
private char[] stackArray;
private int top;
//-------------------------------------------------------------
-
public StackX(int s) // constructor
{
maxSize = s;
stackArray = new char[maxSize];
top = -1;
}
//-------------------------------------------------------------
-
public void push(char j) // put item on top of stack
{ stackArray[++top] = j; }
//-------------------------------------------------------------
-
public char pop() // take item from top of stack
{ return stackArray[top--]; }
//-------------------------------------------------------------
-
public char peek() // peek at top of stack
{ return stackArray[top]; }
//-------------------------------------------------------------
-
public boolean isEmpty() // true if stack is empty
{ return (top == -1); }
//-------------------------------------------------------------
public int size() // return size
{ return top+1; }
//-------------------------------------------------------------
-
public char peekN(int n) // return item at index n
{ return stackArray[n]; }
//-------------------------------------------------------------
-
public void displayStack(String s)
{
System.out.print(s);
System.out.print("Stack (bottom-->top): ");
for(int j=0; j<size(); j++)
{
System.out.print( peekN(j) );
System.out.print(' ');
- 132 -
}
System.out.println("");
}
//-------------------------------------------------------------
-
} // end class StackX
// infix to postfix conversion
{
private StackX theStack;
private String input;
private String output = "";
//-------------------------------------------------------------
-
public InToPost(String in) // constructor
{
input = in;
int stackSize = input.length();
theStack = new StackX(stackSize);
}
//-------------------------------------------------------------
-
public String doTrans() // do translation to postfix
{
for(int j=0; j<input.length(); j++)
{
char ch = input.charAt(j);
theStack.displayStack("For "+ch+" "); // *diagnostic*
switch(ch)
{
case '+': // it's + or -
case '-':
gotOper(ch, 1); // go pop operators
break; // (precedence 1)
case '*': // it's * or /
case '/':
gotOper(ch, 2); // go pop operators
break; // (precedence 2)
case '(': // it's a left paren
theStack.push(ch); // push it
break;
case ')': // it's a right paren
gotParen(ch); // go pop operators
break;
default: // must be an operand
output = output + ch; // write it to output
break;
} // end switch
- 133 -
} // end for
while( !theStack.isEmpty() ) // pop remaining opers
{
theStack.displayStack("While "); // *diagnostic*
output = output + theStack.pop(); // write to output
}
theStack.displayStack("End "); // *diagnostic*
return output; // return postfix
} // end doTrans()
//-------------------------------------------------------------
-
public void gotOper(char opThis, int prec1)
{ // got operator from
input
while( !theStack.isEmpty() )
{
char opTop = theStack.pop();
if( opTop == '(' ) // if it's a '('
{
theStack.push(opTop); // restore '('
break;
}
else // it's an operator
{
int prec2; // precedence of new op
if(opTop=='+' || opTop=='-') // find new op prec
prec2 = 1;
else
prec2 = 2;
if(prec2 < prec1) // if prec of new op
less
{ // than prec of old
theStack.push(opTop); // save newly-popped op
break;
}
else // prec of new not less
output = output + opTop; // than prec of old
} // end else (it's an operator)
} // end while
theStack.push(opThis); // push new operator
} // end gotOp()
//-------------------------------------------------------------
-
public void gotParen(char ch)
{ // got right paren from
input
while( !theStack.isEmpty() )
{
char chx = theStack.pop();
if( chx == '(' ) // if popped '('
break; // we're done
- 134 -
else // if popped operator
output = output + chx; // output it
} // end while
} // end popOps()
//-------------------------------------------------------------
-
} // end class InToPost
class InfixApp
{
public static void main(String[] args) throws IOException
{
String input, output;
while(true)
{
System.out.print("Enter infix: ");
System.out.flush();
input = getString(); // read a string from kbd
if( input.equals("") ) // quit if [Enter]
break;
// make a translator
InToPost theTrans = new InToPost(input);
output = theTrans.doTrans(); // do the translation
System.out.println("Postfix is " + output + '/n');
} // end while
} // end main()
//-------------------------------------------------------------
-
public static String getString() throws IOException
{
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(isr);
String s = br.readLine();
return s;
}
//-------------------------------------------------------------
-
} // end class InfixApp
Listing 4.8 The postfix.java Program
// postfix.java
// parses postfix arithmetic expressions
// to run this program: C>java PostfixApp
import java.io.*; // for I/O
class StackX
{
private int maxSize;
private int[] stackArray;
private int top;
//-------------------------------------------------------------
-
public StackX(int size) // constructor
{
maxSize = size;
stackArray = new int[maxSize];
top = -1;
}
//-------------------------------------------------------------
-
public void push(int j) // put item on top of stack
- 138 -
{ stackArray[++top] = j; }
//-------------------------------------------------------------
-
public int pop() // take item from top of stack
{ return stackArray[top--]; }
//-------------------------------------------------------------
-
public int peek() // peek at top of stack
{ return stackArray[top]; }
//-------------------------------------------------------------
-
public boolean isEmpty() // true if stack is empty
{ return (top == -1); }
//-------------------------------------------------------------
-
public boolean isFull() // true if stack is full
{ return (top == maxSize-1); }
//-------------------------------------------------------------
-
public int size() // return size
{ return top+1; }
//-------------------------------------------------------------
-
public int peekN(int n) // peek at index n
{ return stackArray[n]; }
//-------------------------------------------------------------
-
public void displayStack(String s)
{
System.out.print(s);
System.out.print("Stack (bottom-->top): ");
for(int j=0; j<size(); j++)
{
System.out.print( peekN(j) );
System.out.print(' ');
}
System.out.println("");
}
//-------------------------------------------------------------
-
} // end class StackX
class ParsePost
{
private StackX theStack;
- 139 -
private String input;
//-------------------------------------------------------------
-
public ParsePost(String s)
{ input = s; }
//-------------------------------------------------------------
-
public int doParse()
{
theStack = new StackX(20); // make new stack
char ch;
int j;
int num1, num2, interAns;
for(j=0; j<input.length(); j++) // for each char,
{
ch = input.charAt(j); // read from input
theStack.displayStack(""+ch+" "); // *diagnostic*
if(ch >= '0' && ch <= '9') // if it's a number
theStack.push( (int)(ch-'0') ); // push it
else // it's an operator
{
num2 = theStack.pop(); // pop operands
num1 = theStack.pop();
switch(ch) // do arithmetic
{
case '+':
interAns = num1 + num2;
break;
case '-':
interAns = num1 - num2;
break;
case '*':
interAns = num1 * num2;
break;
case '/':
interAns = num1 / num2;
break;
default:
interAns = 0;
} // end switch
theStack.push(interAns); // push result
} // end else
} // end for
interAns = theStack.pop(); // get answer
return interAns;
} // end doParse()
} // end class ParsePost
- 140 -
class PostfixApp
{
public static void main(String[] args) throws IOException
{
String input;
int output;
while(true)
{
System.out.print("Enter postfix: ");
System.out.flush();
input = getString(); // read a string from kbd
if( input.equals("") ) // quit if [Enter]
break;
// make a parser
ParsePost aParser = new ParsePost(input);
output = aParser.doParse(); // do the evaluation
System.out.println("Evaluates to " + output);
} // end while
} // end main()
//-------------------------------------------------------------
-
public static String getString() throws IOException
{
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(isr);
String s = br.readLine();
return s;
}
//-------------------------------------------------------------
-
} // end class PostfixApp
 
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值