一、线性表的定义
线性表是具有相同类型数据的一个有限序列,数据与数据之间存在着线性关系。线性表中元素的个数称为线性表的长度。如果长度为0,则为空表。元素的序号是从1开始的。一般表示为:
(a1,a2,a3,...,an)
(
a
1
,
a
2
,
a
3
,
.
.
.
,
a
n
)
用二元组表示为:
linear_list = (A,R)
A={ai|1≤i≤n,n≥0} A = { a i | 1 ≤ i ≤ n , n ≥ 0 }
R={<ai,ai+1>|1≤i≤n−1} R = { < a i , a i + 1 > | 1 ≤ i ≤ n − 1 }
线性表与集合的本质区别在于增加和删除:线性表增加一个元素时,所有的元素需要依次向前移动,而集合只是在表头与表尾插入元素即可。删除时,线性表也需要依次移动元素,而集合只是单纯的将最后一个元素移动到删除的位置即可。而且,集合的元素因为没有顺序(只是存储结构如数组是有顺序的,但元素可以放在任意的位置)所以元素是不能重复的。线性表是可以重复的。另一个不同是,线性表需要实现compareTo方法,将元素进行排序,集合是没有顺序而言的。
二、实现过程
- List接口
package list;
public interface List {
//返回线性表的第pos个元素的值
Object value(int pos);
//向第pos位置插入元素obj
boolean add(Object obj,int pos);
//删除pos位置上的元素
Object remove(int pos);
//从第pos位置开始查找元素Obj,找到后返回该元素的位置
int find(Object obj,int pos);
//修改线性表中给定序号的元素值
boolean modify(Object obj,int pos);
//判断是否为空
boolean isEmpty();
//返回线性表的元素的个数
int size();
//正序遍历线性表的元素
void nextOrder();
//反序遍历线性表的元素
void preOrder();
//清空元素
void clear();
//根据当前线性表排序生成新的有序表并返回
List sort();
}
- SequenceList
package list;
public class SequenceList implements List {
final int maxSize = 10;
//用于存放线性表的数组
private Object[] listArray;
private int length;
public SequenceList() {
listArray = new Object[maxSize];
length = 0;
}
public SequenceList(int n) {
if (n <= 0) throw new IllegalArgumentException("the size of list must > 0");
listArray = new Object[n];
length = 0;
}
//这里的pos是线性表元素的position,从1开始
@Override
public Object value(int pos) {
if (pos <= 0 || pos > length) throw new IllegalArgumentException("the position must >=0 or <= length");
return listArray[pos - 1];
}
/**
* 1.判断pos是否合法,如果不合法则返回false,添加的时候可以在1~length+1的任意位置插入。
* 2.如果合法,判断listArray是否已经用完,依据是当前list的length与listArray的长度是否相等,如果相等则说明数组已经用完,需要扩容一倍。
* 3.数组没有用完,将下标为pos-1到length-1的元素移动到下标为pos~length的位置。
* 4.将pos位置空出来放入新增的元素。
*
* @param obj
* @param pos
* @return
*/
@Override
public boolean add(Object obj, int pos) {
if (pos < 1 || pos > length + 1) {
System.out.println("参数不合法");
return false;
}
if (length == listArray.length) {
Object[] tempArray = new Object[2 * length];
for (int i = 0; i < length; i++) tempArray[i] = listArray[i];
listArray = tempArray;
}
for (int i = length; i >= pos; i--) listArray[i] = listArray[i - 1];
//把obj插入到下标为pos-1的位置
listArray[pos - 1] = obj;
length++;
return true;
}
/**
* 1.判断参数是否合法:1~length-1算作合法
* 2.如果合法,将第pos位置的元素暂存下来
* 3.将线性表中第pos+1到length的元素向前移动一个位置。
* 4.length-1
* 5.返回位置为pos的元素
*
* @param pos
* @return
*/
@Override
public Object remove(int pos) {
if (pos < 1 || pos > length) {
System.out.println("参数不合法");
return null;
}
Object tempObj = listArray[pos - 1];
for (int i = pos; i < length; i++) listArray[i - 1] = listArray[i];
length--;
return tempObj;
}
/**
* @param obj
* @param pos
* @return int 为元素的位置,而不是在listArray中的位置
*/
@Override
public int find(Object obj, int pos) {
if (pos < 1 || pos > length) {
System.out.println("参数不合法");
System.exit(1);
}
for (int i = pos - 1; i < length; i++) if (obj.equals(listArray[i])) return i + 1;
//返回-1表示查找失败
return -1;
}
@Override
public boolean modify(Object obj, int pos) {
if (pos < 1 || pos > length) {
System.out.println("参数不合法");
return false;
}
listArray[pos - 1] = obj;
return true;
}
@Override
public boolean isEmpty() {
return length == 0;
}
@Override
public int size() {
return length;
}
//不太严紧
@Override
public void nextOrder() {
for (int i = 0; i < length; i++) {
System.out.println(listArray[i].toString());
}
}
@Override
public void preOrder() {
for (int i = length - 1; i >= 0; i--) {
System.out.println(listArray[i].toString());
}
}
@Override
public void clear() {
length = 0;
}
/**
* 使用选择排序对List进行排序,注意算法的实现,可以对比后边的简单排序
*
* @return
*/
@Override
public List sort() {
SequenceList list = new SequenceList(length);
list.length = length;
//把当前listArray中的数据拷贝到list中
for (int i = 0; i < length; i++) list.listArray[i] = listArray[i];
//定义一个全局的i,j
int i, j;
Comparable x, y;
for (i = 1; i < list.length; i++) {
x = (Comparable) list.listArray[i];
for (j = i - 1; j >= 0; j--) {
y = (Comparable) list.listArray[j];
if (x.compareTo(y) < 0) list.listArray[j + 1] = list.listArray[j];
else break;
}
list.listArray[j + 1] = x;
}
return list;
}
@Override
public String toString() {
int iMax = length - 1;
if (iMax == -1) return "()";
StringBuilder sb = new StringBuilder();
sb.append("(");
for (int i = 0; ; i++) {
sb.append(String.valueOf(listArray[i]));
if (i == iMax) return sb.append(")").toString();
sb.append(", ");
}
}
}
- SequenceListTest
package listTest;
import list.SequenceList;
public class SequenceListTest {
public static void main(String[] args) {
SequenceList sequenceList = new SequenceList();
sequenceList.add("ok",1);
sequenceList.add("hello",1);
sequenceList.add("world",1);
System.out.println(sequenceList);
System.out.println(sequenceList.value(3));
//sequenceList.remove(2);
System.out.println(sequenceList);
//sequenceList.modify("world",2);
sequenceList.nextOrder();
sequenceList.preOrder();
sequenceList.clear();
sequenceList.add(3,1);
sequenceList.add(5,2);
sequenceList.add(2,3);
System.out.println(sequenceList);
System.out.println(sequenceList.sort());
}
}
- 简单排序
package book;
/**
* 简单排序,思路是假设第一个是最大值,从第二数到所最后一个分别与第一个数比较大小,
* 如果比第一个数大,则进行交换。
* 然后再假设第二个数是第二大的数,从三个数到最后一个数分别与第二个数进行比较,如果比第二个数大,则进行交换,
* 这样就可以找到第二大的数。
* 以此类推,将所有数据进行排序。
*/
public class SelectOrder {
public static int[] select(int[] array) {
for (int i = 0; i < array.length; i++) {
for (int j = i + 1; j < array.length; j++) {
if (array[i] < array[j]) {
int temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
}
return array;
}
public static void main(String[] args) {
int[] arr = new int[]{3, 66, 32, 201, 4};
int[] array = select(arr);
for (int i = 0; i < array.length; i++) {
System.out.print(array[i] + " ");
}
}
}