数据结构和算法的内容介绍
几个经典的算法面试题
1.有一个字符串str1和str2,str1=“硅硅谷 尚硅谷你尚硅谷尚硅谷···”,和一个子串str2=“尚硅谷你尚硅你”。
-
判断str1是否含有str2,如果存在,就返回第一次出现的位置,如果没有,则返回-1
-
要求用最快的速度来完成匹配
-
你的思路是什么?
KMP算法(字符串匹配算法)创建部分匹配表
2.汉诺塔游戏,完成汉诺塔游戏的代码:要求:
-
将A塔的所有圆盘移动到C塔,并规定,在2)小圆盘上不能放大圆盘,3)在三根柱子之间一次只能移动一个圆盘
分治算法
3.八皇后问题,古老而著名的问题,是回溯算法的典型案例,该问题是国际西洋棋手马克斯·贝瑟尔于1848年提出,在8*8格的国际象棋上摆放八个皇后,使其不能互相攻击,既:任意两个皇后都不能处于同一行,同一列或同一斜线上,问有多少种摆法?
使用回溯算法(递归)
4.马踏棋盘算法也被称为骑士周游问题:
将马随机放在国际象棋的8*8棋盘,Board[0-7][0-7]的某个方格中,马按走棋规则(马走日字)进行移动。要求每个方格只进入一次,走遍棋盘上全部64个方格。
图的深度优先遍历算法+贪心算法
数据结构与算法的关系
数据data,结构structure是一门研究组织数据方式的学科,有了编程语言也就有了数据结构,学好数据结构可以编写出更加漂亮,更加有效率的代码。
几个实际编程中遇到的问题
public static void main(String[] args) {
String str="Java,Java,hello.world!"
String newstr=str.replaceAll("Java","尚硅谷~");
System.out.println("newstr= "+newstr);
}
问:试写出用单链表表示的字符串类及字符串结点类的定义,并依次实现它的构造函数,以及计算串长度、串赋值、判断两串相等、求子串、两串连接、求子串在串中位置等7个成员函数。
2.约瑟夫(Josephu)问题(丢手帕问题)
- Josephu问题为:设编号为1,2···n的n个人围坐一圈,约定编号为k(1<=k<=n)的人从1开始报数,数列m的那个人出列,它的下一位又从1开始报数,数到m的那个人出列,依次类推,直到所有人出列为止,由此产生一个出队编号的序列。
- 提示:用一个不带头结点的循环链表来处理Josephu问题,先构成一个有n个结点的单循环链表,然后由k结点起从1开始计数,计到m时,对应从链表删除,然后再从被删除结点的下一个结点从1开始计数,直到最后一个结点从链表中删除。
3.五子棋问题
- 棋盘 二维数组->稀疏数组->写入文件[存档]
- 读取文件->稀疏数组->二维数组->棋盘[接上局]
数据结构类型
线性结构:数组、队列、链表、栈
非线性结构:二维数组、多维数组、广义表、树、图
稀疏数组
稀疏数组:当一个数组中大部分元素为0,或者为同一个值的数组时,可以使用稀疏数组来保存该数组。
稀疏数组的处理方法是:
- 记录数组一共有几行几列,有多少个不同的值
- 把具有不同值的元素行列及值记录在一个小规模的数组中,从而缩小程序的规模
稀疏数组的应用实例
row | col | val |
---|---|---|
11 | 11 | 2 |
1 | 2 | 1 |
2 | 3 | 2 |
二维数组转稀疏数组的思路:
- 遍历原始的二维数组,得到有效数据的个数sum
- 根据sum就可以创建稀疏数组sparseArr int[sum+1][3]
- 将二维数组的有效数据存入到稀疏数组
稀疏数组转原始的二维数组的思路
- 根据第一行的数据创建原始的二维数组,比如上面的chessArr2=int[11][11]
- 在读取稀疏数组后几行的数据,并赋给原始的二维数组即可
代码如下:
package com.sparsearray;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
public class SparseArray {
public static void main(String[] args)throws IOException {
//创建一个原始的二维数组
//0表示没有棋子,1表示黑子,2表示蓝子
int chessArr1[][] = new int[11][11];
chessArr1[1][2] = 1;
chessArr1[2][3] = 2;
chessArr1[4][6] = 2;
//输出原始的二维数组
System.out.println("原始的二维数组");
for(int[] row:chessArr1) {
for(int data:row) {
System.out.printf("%d\t",data);
}
System.out.println();
}
//将二维数组转成稀疏数组
//遍历二维数组,得到非0数据的个数
int sum = 0;
for(int i=0;i<11;i++) {
for(int j=0;j<11;j++) {
if(chessArr1[i][j]!=0) {
sum++;
}
}
}
System.out.println("sum="+sum);
//创建对应的稀疏数组
int sparseArr[][] = new int[sum+1][3];
sparseArr[0][0]=11;
sparseArr[0][1]=11;
sparseArr[0][2]=sum;
//遍历二维数组,将非0的值存放到稀疏数组中
int count = 0;//用于记录是第几个非0数据
for(int i=0;i<11;i++) {
for(int j=0;j<11;j++) {
if(chessArr1[i][j]!=0) {
count++;
sparseArr[count][0]=i;
sparseArr[count][1]=j;
sparseArr[count][2]=chessArr1[i][j];
}
}
}
//输出稀疏数组的形式
System.out.println();
System.out.println("得到稀疏数组为");
for(int i=0;i<sparseArr.length;i++) {
System.out.printf("%d\t%d\t%d\t\n",sparseArr[i][0],sparseArr[i][1],sparseArr[i][2]);
}
System.out.println();
System.out.println();
//使用sparse.txt文件来保存稀疏数组
File f=new File("F:\\eclipse\\java-oxygen\\workspace\\DataStructures\\src\\com\\sparsearray\\sparse.txt");
FileOutputStream f1 = new FileOutputStream(f);
OutputStreamWriter fw = new OutputStreamWriter(f1,"UTF-8");//打开文件输出流
for(int i=0;i<sparseArr.length;i++) {
fw.write(sparseArr[i][0]);
fw.write(",");
fw.write(sparseArr[i][1]);
fw.write(",");
fw.write(sparseArr[i][2]);
fw.write(",");
}
fw.close();//写入成功
f1.close();
FileInputStream f2 = new FileInputStream(f);
InputStreamReader fr = new InputStreamReader(f2,"UTF-8");
StringBuffer sb = new StringBuffer();
while(fr.ready()) {
sb.append((char)fr.read());
}
fr.close();
f2.close();
String ss = sb.toString();
System.out.println(ss);
System.out.println();
//将稀疏数组——>恢复成原始的二维数组
//先根据第一行的数据创建原始的二维数组
int chessArr2[][] = new int[sparseArr[0][0]][sparseArr[0][1]];//初始化原始的二维数组
//再读取稀疏数组后几行的数据,并赋给原始的二维数组即可
for(int i=1;i<sparseArr.length;i++) {
chessArr2[sparseArr[i][0]][sparseArr[i][1]] = sparseArr[i][2];
}
//输出恢复后的二维数组
System.out.println();
System.out.printf("恢复后的二维数组\n");
for(int row[]:chessArr2) {
for(int data:row) {
System.out.printf("%d\t",data);
}
System.out.println();
}
}
}
}