プログラミングでは、自明なアルゴリズムの重要性は、プログラムのアルゴリズムは魂がないわけではありません。これは、アルゴリズムの重要性を示しています。
しかし、私たちはデータ構造を持っている必要があり、アルゴリズムを学習する前に、データ構造、アルゴリズムの基礎です。
私が大学にいたC言語は非常に理解がないので、データ構造の学校が、基本的にも、C言語で使用され、インターネットでいくつかの学習教材の特に十分に把握ではない、教えるためにC言語で書かれていますデータ構造を教えます。
だから、この資料の冒頭から、私は、データ構造がアルゴリズムである後に、当然のことながら、データ構造を導入するためにJava言語を使用します。
線形および非線形の構造的構成
- 線形構造の
データ要素間の1つの線形関係が存在することを特徴とする、最も一般的に使用されるデータ構造、等の直鎖状構造、
線状構造は、二つの異なる構造、すなわち、シーケンシャルストレージ構造とチェーン記憶構造に記憶されます。テーブルを記憶する線形配列表の順序と呼ばれるテーブル要素に格納された配列が連続的である、
リンクされた記憶テーブル要素に格納された線形リンクリストは、要素ノードと記憶された隣接するデータ要素、必ずしも連続していないと呼ばれます;情報要素取り組む
配列、キュー、リンクリスト、およびスタック:一般的な線形構造を - 非線形構造
非線形構造であって、二次元アレイ、多次元アレイ、一般化されたテーブル、ツリー構造は、図の構造。
スパース配列
予備的な理解を持っているデータ構造の後、我々はいくつかの具体的なデータ構造を詳細に分析を開始しました。
のは、実際の需要を見てみましょう:
これは保存して終了し、ディスクを継続する機能を有するバックギャモンプログラムで、以下に示すように、次の図のチェスゲームは、それを保存する方法?
この質問は非常に簡単であることを、多くの人が店に2次元配列を使用するのではと思うかもしれません。
上記のように記録が、センスデータの多くを作成しませんように、2次元配列の値の多くは、デフォルト値の0であるため、私たちは、このプログラムを、0と1つの黒点、2バスケット子を発現しないが、大きな問題、今回は疎な配列を用いた2次元アレイの圧縮を行うことができるであろう。
だから、最終的にどのようなスパース配列は、それは何ですか?
配列内の要素の大部分が0である場合、または同一の配列の値は、疎なアレイは、アレイを保持するために使用することができる場合。
治療法のスパース配列は以下のとおりです。
- レコードの配列は、いくつかの奇数行、どのように多くの異なる値の合計
- 要素のランクは異なる値を有し、その値は小さいアレイに記録され、それによってプログラムの小型化
だから、スパース配列の概念を理解し、我々はおよそ331手順スパース配列によって改善しました。
圧縮スパースアレイの後、11月11日元のラインから元の配列は3行3列になります。
疎な配列の最初のラインを記録する行数と列数と元の配列の要素数です。
各後続行は記録され、素子の有効位置の値は、例えば、第二行は1、2位に位置し、元の記録素子アレイである;そして元の配列の第三の行は3位に位置しています2つの要素。
要約すると、スパース配列に2次元配列のアイデア:
- 保存する元の2次元アレイ、要素の有効数のトラバーサル
- 有効な要素の数に応じてsparseArr疎なアレイを作成します
- 有効なデータの二次元アレイは、スパースアレイに記憶することができます
独創的なアイデアの二次元配列にスパース配列:
- 最初の行は、最初の行のデータに基づいて、元の2次元配列を作成する最初の疎な配列を読み取ります
- データスパースアレイの数行を読んだ後、元の二次元アレイに割り当てることができます
アイデアの実現が分析されたについて、次のコードが実行されます。
次のコードで実装スパースアレイの二次元アレイ。
public static void main(String[] args) {
// 创建一个原始的二维数组(11行11列)
// 0:表示没有棋子
// 1:表示黑子
// 2:表示蓝子
int chessArr1[][] = new int[11][11];
chessArr1[1][2] = 1;
chessArr1[2][3] = 2;
System.out.println("原始的二维数组:");
for (int[] row : chessArr1) {
for (Integer value : row) {
System.out.printf("%d\t", value);
}
System.out.println();
}
// 将二维数组转稀疏数组
// 先遍历二维数组,得到非0的元素个数
int sum = 0;
for (int i = 0; i < chessArr1.length; i++) {
for (int j = 0; j < chessArr1[i].length; j++) {
if (chessArr1[i][j] != 0) {
sum++;
}
}
}
// 创建对应的稀疏数组
int sparseArr[][] = new int[sum + 1][3];
// 给稀疏数组赋值
// 稀疏数组第一行存的是原始数组的行数、列数和有效元素个数
sparseArr[0][0] = chessArr1.length;
sparseArr[0][1] = chessArr1[0].length;
sparseArr[0][2] = sum;
// 遍历二维数组,将非0的值存入到稀疏数组中
int count = 0; // 用于记录是第几个非0数据
for (int i = 0; i < chessArr1.length; i++) {
for (int j = 0; j < chessArr1[i].length; 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[] row : sparseArr) {
for (Integer value : row) {
System.out.printf("%d\t", value);
}
System.out.println();
}
}
結果は以下の通りであります:
原始的二维数组:
0 0 0 0 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0 0 0
0 0 0 2 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
稀疏数组:
11 11 2
1 2 1
2 3 2
このように、我々は、スパース配列に2次元配列に成功しました。
それでは、どのコードの2次元配列への疎な配列を行いますか?
// 将稀疏数组转为二维数组
// 先读取稀疏数组的第一行,根据第一行的数据创建原始数组
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.println("恢复后的二维数组:");
for (int[] row : chessArr2) {
for (Integer value : row) {
System.out.printf("%d\t", value);
}
System.out.println();
}
スレッドのクリアランスを考えた後、コードは営業成績を見て、非常に簡単です:
原始的二维数组:
0 0 0 0 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0 0 0
0 0 0 2 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
稀疏数组:
11 11 2
1 2 1
2 3 2
恢复后的二维数组:
0 0 0 0 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0 0 0
0 0 0 2 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
次のように全体のコードは次のとおりです。
public static void main(String[] args) {
// 创建一个原始的二维数组(11行11列)
// 0:表示没有棋子
// 1:表示黑子
// 2:表示蓝子
int chessArr1[][] = new int[11][11];
chessArr1[1][2] = 1;
chessArr1[2][3] = 2;
System.out.println("原始的二维数组:");
for (int[] row : chessArr1) {
for (Integer value : row) {
System.out.printf("%d\t", value);
}
System.out.println();
}
// 将二维数组转稀疏数组
// 先遍历二维数组,得到非0的元素个数
int sum = 0;
for (int i = 0; i < chessArr1.length; i++) {
for (int j = 0; j < chessArr1[i].length; j++) {
if (chessArr1[i][j] != 0) {
sum++;
}
}
}
// 创建对应的稀疏数组
int sparseArr[][] = new int[sum + 1][3];
// 给稀疏数组赋值
// 稀疏数组第一行存的是原始数组的行数、列数和有效元素个数
sparseArr[0][0] = chessArr1.length;
sparseArr[0][1] = chessArr1[0].length;
sparseArr[0][2] = sum;
// 遍历二维数组,将非0的值存入到稀疏数组中
int count = 0; // 用于记录是第几个非0数据
for (int i = 0; i < chessArr1.length; i++) {
for (int j = 0; j < chessArr1[i].length; 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[] row : sparseArr) {
for (Integer value : row) {
System.out.printf("%d\t", value);
}
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.println("恢复后的二维数组:");
for (int[] row : chessArr2) {
for (Integer value : row) {
System.out.printf("%d\t", value);
}
System.out.println();
}
}