本節是《Java數據結構及算法實戰》系列的第2節,主要介紹描述算法的常用的4種方式。
要定義一個算法,我們可以用自然語言、流程圖、僞代碼的方式描述解決某個問題的過程或是編寫一段程序來實現這個過程。比如,在前面所舉的“學生信息管理系統”例子中,我們希望實現添加用戶、刪除用戶、查詢用戶三個算法。
1. 自然語言描述算法
可以採用自然語言的方式來描述添加用戶、刪除用戶、查詢用戶三個算法:
- 添加用戶:將用戶信息添加到系統中。如果已經添加了過該用戶的信息,則提示用戶。否則將用戶信息添加到系統中,並給出提示。
- 刪除用戶:將用戶信息從系統中刪除。如果用戶信息不存在於系統中,則提示用戶。否則將用戶信息從系統中刪除,並給出提示。
- 查詢用戶:將系統中所有的用戶信息查詢出來。如果系統中不存在用戶,則提示用戶。否則將用戶信息查詢出來返回,並將用戶信息打印出來。
使用自然語言描述的好處是任何人都能看懂。當然相比於僞代碼或者程序語言而言,使用自然語言描述有時會顯得繁瑣。
2. 流程圖描述算法
流程圖(Flow Diagram)是一種通用的圖形符號表示法是一種非正式的,可以清楚描述步驟和判斷。圖1-2展示的是用流程圖的方式來描述添加用戶、刪除用戶、查詢用戶三個算法。
相比較自然語言而言,通過流程圖的描述,可以很清楚的看到操作的流向及經過的步驟。但需要注意的是,流程圖應該只描述核心的操作步驟以及關鍵的節點判斷,而不是事無鉅細的把所有的操作都描述出來,否則只會讓整個圖看上去複雜難以理解。
3. 僞代碼描述算法
僞代碼(Pseudocode)是一種非正式的,類似於英語結構的,用於描述模塊結構圖的語言。可以採用僞代碼的方式來描述添加用戶、刪除用戶、查詢用戶三個算法。
添加用戶的僞代碼如下:
input(student)
if student in studentList
print "Student exsit"
else
add student in studentList
print "Add student success"
刪除用戶的僞代碼如下:
input(student)
if student in studentList
remove student from studentList
print "Remove student success"
else
print "Student not exsit"
查詢用戶的僞代碼如下:
if student in studentList
output studentList
else
print "No student exsit"
僞代碼結構清晰、代碼簡單、可讀性好,並且類似自然語言。介於自然語言與編程語言之間。以編程語言的書寫形式指明算法職能。使用僞代碼,不用拘泥於具體實現。相比程序語言(例如Java、C++、C等等)它更類似自然語言。它雖然不是標準的語言,卻可以將整個算法運行過程的結構用接近自然語言的形式(可以使用任何一種你熟悉的文字,關鍵是把程序的意思表達出來)描述出來。
4. 程序語言描述算法
程序語言描述算法,實際上就是用程序語言實現算法。不同的編程語言其語法不盡相同。以下是採用Java語言的方式來描述添加用戶、刪除用戶、查詢用戶三個算法。
import java.util.ArrayList;
import java.util.List;
public class StudentInfoManageSystem {
private List<Student> studentList = new ArrayList<>();
public void addStudent(Student student) {
// 如果已經添加了過該用戶的信息,則提示用戶。
// 否則將用戶信息添加到系統中,並給出提示。
if (studentList.contains(student)) {
System.out.println("Student exsit");
} else {
studentList.add(student);
System.out.println("Add student success");
}
}
public void removeStudent(Student student) {
// 如果用戶信息不存在於系統中,則提示用戶。
// 否則將用戶信息從系統中刪除,並給出提示。
if (studentList.contains(student)) {
studentList.remove(student);
System.out.println("Remove student success");
} else {
System.out.println("Student not exsit");
}
}
public List<Student> getStudentList() {
// 如果系統中不存在用戶,則提示用戶。
// 否則將用戶信息查詢出來返回,並將用戶信息打印出來。
if (studentList.isEmpty()) {
System.out.println("No student exsit");
} else {
for (Student s : studentList) {
System.out.format("Student info: name %s, age %d, phone %s, address %s%n",
s.getName(), s.getAge(), s.getPhoneNumer(), s.getAddress());
}
}
return studentList;
}
}
爲了演示上述算法,還需要一個應用入口。我們用StudentInfoManageSystemDemo類來表示應用主程序,代碼如下:
import java.util.ArrayList;
import java.util.List;
public class StudentInfoManageSystemDemo {
public static void main(String[] args) {
// 初始化系統
StudentInfoManageSystem system = new StudentInfoManageSystem();
// 初始化學生信息
Student student = new Student(32, "Way Lau", "17088888888", "Shenzhen");
// 添加學生
system.addStudent(student); // Add student success
// 再次添加學生
system.addStudent(student); // Student exsit
// 第一次查詢所有學生
List<Student> studentList = system.getStudentList();
// 刪除學生
system.removeStudent(student); // Remove student success
// 再次刪除學生
system.removeStudent(student); // Student not exsit
// 查詢所有學生
studentList = system.getStudentList(); // No student exsit
}
}
運行上述程序,可以看到控制檯輸出內容如下:
Add student success
Student exsit
Student info: name Way Lau, age 32, phone 17088888888, address Shenzhen
Remove student success
Student not exsit
No student exsit
程序語言描述算法一步到位,寫出的算法可直接交予計算機處理。對於懂得這類程序語言的開發者而言,通過運行程序可以馬上驗證算法的正確性。當然其缺點也較爲明顯:
- 不便於體現自頂向下、逐步求解的思想;
- 程序語言包含很多細節內容,會淹沒算法的主要思想。
因此,在描述某個算法時,往往通過幾種描述方式結合起來使用。