线性表:
定义:线性表是一种线性结构。特点是数据元素之间是线性关系,数据元素“一个接一个的排列“;并且,在一个线性表中所有数据元素的类型都是相同的。
特点:
1. 存在唯一一个称为”第一个“的元素
2. 存在唯一一个称为”最后一个“的元素
3. 除第一个元素之外,序列中的每一个元素只有一个直接前驱
4. 除最后一个元素之外,序列中的每一个元素只有一个直接后继
**存储结构**
顺序存储 顺序表
链式存储 链表
- 顺序表
线性表的顺序存储是用一组地址连续的存储单元按顺序存放线性表中的每一个元素(数据元素),这种存储方式的线性表称为顺序表。
顺序表中两个重要属性 数据 表长
顺序表的操作:初始化 建立 插入 删除 查找
初始化 即构造一个空表
建立 依次输入长度为n的每个数据元素值
插入 给某个确定位置插入一个新元素,先将其余元素后移,将新元素插入到移除的位置,表长度+1
删除 将表中第i个位置的元素删除 用“将后面元素前移”实现
查找 查找是否顺序表中存在要查找的元素值,返回元素位置
注意:对顺序表进行操作,注意是否表为空,是否位置合法等
import java.util.Scanner;
import static com.dataStruct.LNode.InsertIntolnode;
import static com.dataStruct.LNode.deleteLinklist;
class LNode {
int data;//数据域
LNode next = null;//指针域
public LNode() {
}
public LNode(int data) {
this.data = data;
}
public static void GetLinklistlong(LNode head){//获取
LNode L= new LNode();//新申请一个结点
L=head;//将其指向头结点
int count=0;
while (L.next!=null){
L=L.next;//已经有一个结点了,所以新结点指向下一个结点
count++;
}
System.out.println("表长为"+count);
}
public static LNode getLinkListByNum(LNode head,int i){//按链表元素位置查找
/*按结点数据域的值查找,也是新申请一个结点P,指向头结点,当P.NEXT!=NULL&&P.data!=要找的值时,寻找,返回结点*/
int j=0;
LNode P = new LNode();
P=head;
while(P.next!=null&&j<i){
P=P.next;
j++;
}
return P;//书上写的返回指针,这里返回的结点,在主函数里将地址打印,但也着实不知道到底找到了没。
// 即使输出数据域,要是没找到那么输出最后一个结点的数据域,要是找的是最后一个元素,那么也输出最后一个数的数据域,所以无法判断找到了没。
}
public static void InsertIntolnode(LNode head){//插入结点
System.out.println("请输入要插入结点的位置和值");
Scanner scanner = new Scanner(System.in);
int i = scanner.nextInt();
int x = scanner.nextInt();
LNode P,Q;
P=getLinkListByNum(head,i-1);//将结点P指向想要插入位置的结点,要是返回值为空,则查找位置不存在
if(P==null) {
System.out.println("插入位置非法");
return;
}
else {
Q=new LNode();//申请结点空间
Q.data=x;
Q.next=P.next;
P.next=Q;
System.out.print("插入数据后");
LNode.toString(head);
}
}
public static void deleteLinklist(LNode head){//删除结点
System.out.println("请输入删除结点的位置");
Scanner scanner = new Scanner(System.in);
int i=scanner.nextInt();
LNode P,Q;
P=getLinkListByNum(head,i-1);
if(P==null)
System.out.println("第"+(i-1)+"个结点不存在");
else {
if(P.next==null)
System.out.println("第"+i+"个结点不存在");
else {
Q=P.next;
P.next=Q.next;
//这块是释放第i个结点的空间
System.out.print("删除数据后");
LNode.toString(head);
}
}
}
public static String toString(LNode head) {//重写toString方法
if (head.next == null)
System.out.println("链表为空");
else {
System.out.println("链表的数据域值为");
while (head.next != null) {
head = head.next;
System.out.println(head.data + " ");
}
}
return null;
}
}
public class Lianbiao {//测试类
public static void main(String[] args) {
LNode head = new LNode();
CreatLinklist(head);
//LNode.toString(head);//输出链表中所有结点数据域
LNode.GetLinklistlong(head);
// System.out.println(LNode.getLinkListByNum(head,2));
InsertIntolnode(head);
// deleteLinklist(head);
}
public static void CreatLinklist(LNode head) {//初始化顺序表
System.out.println("请输入初始化链表的长度");
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
if (n < 0)
System.out.println("链表长度非法");
while (n > 0) {//尾插法 即新生成的结点排在头(前一个结点)结点之后
System.out.println("请输入链表值");
int DATA = scanner.nextInt();
LNode p = new LNode(DATA);
head.next = p;
head = p;
n--;
}
}
}
缺点:插入删除需要移动大量元素
2.链表(这里暂时只写单链表 )
单链表:由于线性表中的每个元素至多只有一个前驱和一个后继元素,即元素之间是“一对一”的逻辑关系。为了在元素之间建立起这种线性关系,采用链表存储最简单也最常用的方法是:在每个元素中除了含有数据信息外,还要有一个指针用来指向它的直接后继元素,即通过指针建立起元素之间的线性关系,我们称这种元素为结点,结点中存放数据信息的部分称为数据域,存放指向后继结点指针的部分称为指针域,将这种链式存储结构称为链表
相关代码
import java.util.Scanner;
class Seqlist{
public final int MAXSIZE=10000;//MAXSIZE设置为一个最大长度,c里有,Java没,设置为1000
int data[]=new int[MAXSIZE];//数据域 连续的存储单元依次存放
int len;//长度设为0 为了指针域和数据域对应 下面初始化将数据首下标设为1
public void setLen(int len) {
this.len = len;
}
public static void Init_seqlist(Seqlist seqlist){
seqlist.setLen(0);
}
public static void CreatSeqlist(Seqlist seqlist){
System.out.println("input length");
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
for(int i=1;i<=n;i++){
System.out.println("请输入元素");
seqlist.data[i]=scanner.nextInt();
seqlist.len++;
}
System.out.println("表长度为"+seqlist.len);
}
public static void Insert_Seqlist(Seqlist seqlist){//头插法。尾插法没写 基本思想是一个结点始终指向最后结点,然 插入新结点
int i,x;//i为要插入的位置,x为要插入的数据 定义顺序表时,data域设置的int
Scanner scanner = new Scanner(System.in);
System.out.println("请输入要插入的位置和要插入的数据");
i = scanner.nextInt();
x = scanner.nextInt();
int j;
if(seqlist.len==seqlist.MAXSIZE-1){//判断表是否满
System.out.println("表满");
return;
}
else
if(i<1||i>seqlist.len+1)/*判断插入位置*/
System.out.println("插入位置非法");
else {
for(j=seqlist.len;j>i-1;j--){//把要插入位置i及以后的元素向后移动,留出位置待新元素插入
seqlist.data[j+1]=seqlist.data[j];
}
seqlist.data[i]=x;//新元素插入到i号位置
seqlist.len++;//顺序表表长加一
for(j=1;j<=seqlist.len;j++){//遍历一遍,以证明插入成功
System.out.println("第"+j+"个元素"+"data域为"+seqlist.data[j]);
}
}
}
public static void delete_Seqlist(Seqlist seqlist){
System.out.println("请输入要删除的元素的位置");
Scanner scanner = new Scanner(System.in);
int i= scanner.nextInt();
int j;
if(seqlist.len==0){//判断表长,如果为0则无法删除
System.out.println("当前表为空,无法删除");
return;
}
else {
if(i<1||i>seqlist.len) {//判断要删除的位置是否在表中存在
System.out.println("删除位置非法");
return;
}
else {
for(j=i+1;j<=seqlist.len;j++)
seqlist.data[j-1]=seqlist.data[j];
seqlist.len--;
}
} for(j=1;j<=seqlist.len;j++){//遍历一遍,以证明删除成功
System.out.println("第"+j+"个元素"+"data域为"+seqlist.data[j]);
}
}
public static void find_seqlist(Seqlist seqlist){
System.out.println("请输入要查找的元素值");
Scanner scanner = new Scanner(System.in);
int x =scanner.nextInt();
int i=1;
while(i<seqlist.len && x!=seqlist.data[i]){
i++;
if(seqlist.data[i]==x){
System.out.println("你查找的元素位置为"+i);
return;
}
}
System.out.println("你查找的元素不存在");
}
}
public class TestDemo {
public static void main(String[] args) {
Seqlist seqlist = new Seqlist();
Seqlist.Init_seqlist(seqlist);
Seqlist.CreatSeqlist(seqlist);
Seqlist.Insert_Seqlist(seqlist);
Seqlist.delete_Seqlist(seqlist);
Seqlist.find_seqlist(seqlist);
}
}