# 线性结构-实验报告

### 实验项目

• 参考Java Foundation 3rd 第15.6节，用数组实现线性表List
• 参考Java Foundation 3rd 第15.7节，用链表实现线性表List
• 源码分析

### 实验二

aList，bList都是非递减线性表，合并后也是非递减

public static List<？ extends Comparable>mergeSortedList(List<？extends Comparable> aList,  List<？ extends Comparable> bList)


• 源码
public class ArrayTest {

static List<MyArray> mArrayList1 = new ArrayList<>();
static List<MyArray> mArrayList2 = new ArrayList<>();
static List<MyArray> NewArrayList = new ArrayList<>();
public void Setup(){
setup();
}

public static void setup() {

}

public static List<? extends Comparable> mergeSortedList(List<? extends Comparable> aList,
List<? extends Comparable> bList){
setup();
List<Comparable> mlist1 = new ArrayList();

for (int i =0;i<aList.size();i++){
}
for (int i =0;i<bList.size();i++){
}

selectionSort(mlist1);
return mlist1;
}

public  static void selectionSort(List<Comparable> myList){
int min;
for (int index =0;index<myList.size()-1;index++){
min = index;
for (int scan = index+1;scan < myList.size();scan++){
if (myList.get(scan).compareTo(myList.get(min))<0)
min = scan;

}
swap(myList,min,index);

}

}
private static void swap(List<Comparable> myList,int index1,int index2){
List<Comparable> list = new ArrayList();
myList.set(index1,myList.get(index2));
myList.set(index2,list.get(0));

}
}

• 我的思路是：两个线性表都是有序的，所以我定义一个线性表，现将原有表的元素都加入表中，再将表中的元素进行排序，调用selectionSort方法和swap方法，将元素进行比较排列。

### 实验三

• 源码
public class MyList<T> {
private static  int FirstRoom = 20;
private T [] num=(T [])new  Object [FirstRoom];
private int thesize;

public static void setFirstRoom(int firstRoom) {
FirstRoom = firstRoom;
}

public int getThesize() {
return thesize;
}

public static int getFirstRoom() {
return FirstRoom;
}

public void setlist(){
thesize=0;
}
return true;

}
if (index<0){
System.out.println("Wrong number");
}
if (index>thesize){
//ruguo

}
if (index == thesize){
num[index] = t;
}
else if(index<thesize){
for (int i = thesize;i>index;i--){
num[i] =num [i-1];
}
num[index] = t;
}
thesize++;
}
//删除表中的元素 ArrayList remove(Object o)
public boolean remove(T t){
int position = -1;
for (int i=0;i<thesize;i++){
if (num[i]==t){
position = i;
break;
}
}
if (position==-1){
System.out.println("Wrong position");
return false;
}
else {
for (int i= position;i<thesize-1;i++){
num[i] = num[i+1];
}
thesize --;
return true;
}
}
public T get(int index){
T item = num[index];
return item;

}

public boolean isEmpty(){
if (thesize==0){
return true;
}
else return false;

}
}

• 我的思路：首先通过强制转型定义数组private T [] num=(T [])new Object [FirstRoom];private int thesize;是为了反馈数组里的元素个数。
• 添加元素：将元素添加到指定位置，那么原位置的元素向后移。
• 删除元素：删除指定位置的元素，那么原位置元素的后一位向前移。

### 实验四

• 源码

public class Linked<T> {
private int size;
private Point FirstPoint;//表的头
private Point LastPoint;//表的尾

FirstPoint = new Point(null,null,null);//开始表头为空
LastPoint = new Point(null,FirstPoint,null);
FirstPoint.EndPoint=LastPoint;
}
class Point{
T data;
Point EndPoint;
this.data = data;
this.EndPoint = endPoint;
}
};
public int size(){
return this.size;
}
public boolean isEmpty(){
return size()==0;
}
size++;
return true;
}
public void remove(int index) {
Point point = getposition(index);
point.data = null;
point.EndPoint = null;
point = null;
size--;
}
public T get(int index){
Point point = getposition(index);
return point.data;
}
private Point getposition(int index){
Point point;
int i;
for (i =0,point=FirstPoint.EndPoint;i<index;i++){
point = point.EndPoint;
}
return point;
}
}

• 我的思路：我设计的是一个双向链表，一个节点有两个指针，一个指向此节点的前节点，一个指向后一个节点。首先要定义列表中的头尾两个节点，此节点都不存储任何数据。
    firstNode = new Node(null,null,null);
lastNode = new Node(null,firstNode,null);
firstNode.nextNode = lastNode;


• 添加节点：我的添加方式是按顺序添加，首先新建一个节点，前驱节点指向尾节点的前一个节点，后继节点指向尾节点，原先尾节点的前一个节点的后继节点指向我们新建的节点，尾节点的前驱节点指向我们新建的节点。
    public boolean add(T t){
size++;
return true;
}

• 删除节点：我的删除方法是删除指定位置的元素，首先要找到位于该位置的节点，将找到节点的前驱节点的后继结点指向该节点的后继节点，将找到节点的后继结点的前驱节点指向该节点的前驱节点，将该节点的数据域、指针域以及它本身都指向null。
    public void remove(int index) {
Point point = getposition(index);
point.data = null;
point.EndPoint = null;
point = null;
size--;
}
private Point getposition(int index){
Point point;
int i;
for (i =0,point=FirstPoint.EndPoint;i<index;i++){
point = point.EndPoint;
}
return point;
}



• 1.构造函数之一：ArrayList(int initialCapacity)
    public ArrayList(int initialCapacity) {
if (initialCapacity > 0) {
this.elementData = new Object[initialCapacity];
} else if (initialCapacity == 0) {
this.elementData = EMPTY_ELEMENTDATA;
} else {
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
}
}


• 2.函数方法：contains(Object o)
     public boolean contains(Object o) {
return indexOf(o) >= 0;
}

public int indexOf(Object o) {
if (o == null) {
for (int i = 0; i < size; i++)
if (elementData[i]==null)
return i;
} else {
for (int i = 0; i < size; i++)
if (o.equals(elementData[i]))
return i;
}
return -1;
}


contains方法调用了indexOf()方法，而indexOf方法的源码注释：返回列表中第一次出现元素的索引，或者返回-1，如果列表中不存在此元素。indexOf方法处理了三种情况：(1)o ==null,定义一个循环遍历此表，如果出现元素为空的情况则返回此元素的位置。(2)如果o不为空，同样定义 循环，如果o.equals(elementData[i])则返回此元素位置。(3)如果没有次元素则返回-1;而contains方法中将返回的数与0进行比较。

     public void add(int index, E element) {

ensureCapacityInternal(size + 1);
System.arraycopy(elementData, index, elementData, index + 1,
size - index);
elementData[index] = element;
size++;
}

if (index > size || index < 0)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
private void ensureCapacityInternal(int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}

ensureExplicitCapacity(minCapacity);
}
private void ensureExplicitCapacity(int minCapacity) {
modCount++;

// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// minCapacity is usually close to size, so this is a win:
elementData = Arrays.copyOf(elementData, newCapacity);
}

• （3）直接调用System.arraycopy方法，该方法的作用是： ，就好像假定元素组元素有：1,2,3,4,5。他们的编号为0,1,2,3,4。若我们插入6到第二个位置，即为1,2,6,3,4,5。那么经过一次调用System.arraycopy方法后数组暂时变为了：1,2,3,3,4,5。最后只需要将数组的第二个位置的元素赋值为我们要插入的元素即可，本例：elementData[index] = element;