[1]线性表的定义和基本操作
线性表是具有相同特性的数据元素的一个有限序列,该序列中所含元素的个数叫线性表的长度。
线性表的特性:
- 有穷性:一个线性表中的元素个数是有限的。
- 一致性:一个线性表中所有元素的性质相同。所有元素具有相同的数据类型
- 序列性:一个线性表中所有元素之间的行对位置是线性的,即存在唯一的开始元素和终端元素,除此之外,每个元素只有唯一的前驱元素和后继元素。
线性表的基本运算(c++下):
- InitList(&L) :初始化线性表,构造一个空的线性表(Java将放在构造函数中初始化数组)
- DestroyList(&L):销毁线性表,释放线性表L占用的内存空间(Java省略)
- ListEmpty(L):判断线性表是否为空
- ListLength(L):返回线性表的长度
- DispList(L):输出线性表,当线性表L不为空时的顺序显示L中各结点的值域
- GetElem(L,i,&e):求出线性表中某个元素的值,用e返回L中弟i个值
- ListInsert(&L,i,e):插入数据元素,在L的第i个位置插入一个新元素e
- ListDelete(&L,i,&e):删除数据元素,删除L的第i个元素,并且用e返回其值
下面将对上面的这些基本运算以Java来实现。
[2]线性表的实现
为了简便,这里存储的数据类型全都设为了int型。
- 顺序存储结构
线性表的顺序存储结构是把线性表中的所有元素按照其逻辑顺序一次存放到计算机存储器中指定存储位置开始的一块连续的存储空间。由于线性表中逻辑上相邻的两个元素在对应的顺序表中它们的存储位置也相邻,所以这种映射称为直接映射。线性表的顺序存储结构简称为顺序表。
实现的Java代码:
package com.muzile.List.arrayList;
public class MyArrayList {
private int capacity;
private int size;
private int[] list;
/**
* 默认容量的顺序表
*/
public MyArrayList(){
capacity = 16;
list = new int[capacity];
size = 0;
}
/**
* 初始化容量的顺序表
* @param capacity
*/
public MyArrayList(int capacity){
this.capacity = capacity;
list = new int[capacity];
size = 0;
}
/**
* 获得顺序标的大小
* @return
*/
public int size(){
return this.size;
}
/**
* 向线性表中顺序添加一个元素
* @param value
* @return
*/
public boolean add(int value){
if(size==capacity){
return false;
}
list[size] = value;
size++;
return true;
}
/**
* 获得一个指定下标的元素
* @param index
* @return
*/
public int get(int index){
if(index>=size||index<0){
return -1;
}else{
return list[index];
}
}
/**
* 插入一个元素,其他元素向后移动
* @param location
* @param value
* @return
*/
public boolean insert(int location,int value){
if(location<0||location>size||size == capacity){
return false;
}
for(int i=size;i>location;i--){
list[i] = list[i-1];
}
list[location] = value;
size++;
return true;
}
/**
* 删除一个元素,其他元素向前移动
* @param location
* @return
*/
public int remove(int location){
int retVal;
if(location<0||location>=size){
return -1;
}
retVal = list[location];
for(int i = location;i<list.length-1;i++){
list[i]=list[i+1];
}
size--;
return retVal;
}
/**
* 判断顺序表是否为空
* @return
*/
public boolean isEmpty(){
return size==0;
}
/**
* 打印顺序表中的所有元素
*/
public String toString(){
String retStr = "[";
for(int i=0;i<size;i++){
if(i<size-1){
retStr+=list[i]+",";
}else {
retStr+=list[i];
}
}
return retStr+"]";
}
/**
* 测试
* @param args
*/
public static void main(String[] args){
MyArrayList list = new MyArrayList();
for(int i = 0 ;i<16;i++){
list.add(i);
}
System.out.println(list);
System.out.println(list.isEmpty());
System.out.println(list.remove(3));
System.out.println(list.insert(3, 1));
System.out.println(list);
System.out.println(list.get(6));
}
}
运行结果:
[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]
false
3
true
[0,1,2,1,4,5,6,7,8,9,10,11,12,13,14,15]
6
- 链式存储结构
线性表的链式存储结构为链表,其中每个存储结点不仅包含元素本身的信息称之为数据域,而且包含表示元素之间逻辑关系的信息称之为指针域。
由于线性表中的每个元素最多只有一个前驱元素和一个后继元素,所以当采用链式存储时,一种最简单、最常用的方法是在每个结点中除包含有数据域以外只设置一个指针域,用于指向其后继结点,这样构成的链表称之为线性单向链表,简称单链表。
实现的Java代码:
Node类:
package com.muzile.List.linkedList;
public class Node {
private Node next = null;
private int data;
public Node(int data){
this.data = data;
}
public Node getNext() {
return next;
}
public void setNext(Node next) {
this.next = next;
}
public int getData() {
return data;
}
public void setData(int data) {
this.data = data;
}
}
链表类:其中循环查找、删除结点可以改进,将参数下标与size/2比较,分别从两端到中间扫描。
package com.muzile.List.linkedList;
public class MyLinkedList {
private int size;
private Node head = null;
public MyLinkedList(){
size = 0;
}
/**
* 头插法
* @param val
public void add(int val){
Node node = new Node(val);
if(head==null){
head = node;
}else{
node.setNext(head.getNext());
head.setNext(node);
}
size++;
}*/
/**
* 尾插法
* @param val
*/
public void add(int val){
Node node = new Node(val);
if(head==null){
head = node;
}else{
Node p = head;
while(p.getNext()!=null){
p = p.getNext();
}
p.setNext(node);
}
size++;
}
/**
* 插入一个元素
* @param location
* @param val
* @return
*/
public boolean insert(int location,int val){
if(location<0||location>size){
return false;
}
Node node = new Node(val);
if(head==null){
head = node;
}else{
Node sign = head;
Node pre = null;
for(int i=0;i<=location;i++){
if(sign.getNext()!=null){
pre = sign;
sign = sign.getNext();
}else{
sign.setNext(node);
size++;
return true;
}
}
pre.setNext(node);
node.setNext(sign);
}
size++;
return true;
}
/**
* 删除一个元素
* @param index
* @return
*/
public int remove(int index){
int retVal = -1;
if(index<0||index>=size){
return -1;
}
if(head!=null){
Node pre=head,p=head,sign=head;
for(int i=0;i<=index;i++){
pre = p;
p = sign;
sign = sign.getNext();
}
pre.setNext(p.getNext());
retVal = p.getData();
}
size--;
return retVal;
}
/**
* 获得一个元素
* @param index
* @return
*/
public int get(int index){
int retVal = -1;
if(index<0||index>=size){
return retVal;
}
if(head!=null){
Node pre=head,sign=head;
for(int i=0;i<=index;i++){
pre = sign;
sign = sign.getNext();
}
retVal = pre.getData();
}
return retVal;
}
/**
* 返回所有元素的字符串
*/
@Override
public String toString(){
Node p = head;
String retVal = "[";
while(p!=null){
if(p.getNext()!=null){
retVal += p.getData()+",";
}else{
retVal += p.getData()+"";
}
p = p.getNext();
}
return retVal+"]";
}
/**
* 获得链表长度
* @return
*/
public int size(){
return size;
}
/**
* 判空
* @return
*/
public boolean isEmpty(){
return size==0;
}
/**
* 测试
* @param args
*/
public static void main(String[] args){
MyLinkedList list = new MyLinkedList();
for(int i = 0 ; i < 10 ; i++){
list.add(i);
}
System.out.println(list);
System.out.println(list.get(10));
System.out.println(list.remove(9));
System.out.println(list);
System.out.println(list.insert(9, 2));
System.out.println(list);
}
}
结果:
[0,1,2,3,4,5,6,7,8,9]
-1
9
[0,1,2,3,4,5,6,7,8]
true
[0,1,2,3,4,5,6,7,8,2]
本文详细介绍了线性表的定义、特性及其在Java中的两种实现方式:顺序存储结构和链式存储结构。通过具体代码示例,展示了线性表的基本操作,包括初始化、插入、删除等。
343

被折叠的 条评论
为什么被折叠?



