顺序表与链表

顺序表与链表

1.线性表:

是一种在实际中广泛使用的数据结构,n个具有相同的数据元素的有限序列
常见的线性表:顺序表,链表,栈,队列,字符串
在物理结构上不一定是连续的,在物理存储时,通常以数组和链式结构的形式存储

2.顺序表

顺序表使用一段物理地址连续的存储单元一次存储数据元素的数据结构
采用数组存储
分类:静态数据表:使用定长数组存储
动态数据表:使用动态开辟的数组存储

   import   java.util.Arrays;
public class MyArrayList {
    public static void main(String[] args) {
        M m = new M() ;
        m.add(2,3);
        m.add(1,5);
        m.add(3,4);
        m.add(0,1);
        System.out.print(m.elem[0]+" ,");
        System.out.print(m.elem[1]+",");
        System.out.print(m.elem[2]+",");
        System.out.println(m.elem[3]);
        System.out.println("=====");
        System.out.println( m.contains(3));
        System.out.println("=======");
        System.out.println(m.search(3));
        System.out.println("=======");
        System.out.println(m.getPos(3));
        System.out.println("=======");
        m.setPos(2,3);
        System.out.println("=======");
        m.remove(3);
         m.clear();
        System.out.println(m.size());
    }
}

class M {
public int usedSize;//实际存入的数据占用空间的大小
public int[] elem;//保存数据
public final int CAPACITY = 10;

public M() {
    this.usedSize = 0;
    this.elem = new int[CAPACITY];
}
  //打印顺序表
    public void display() {
        for (int x : elem)
            System.out.println(x);
    }
  
 //判断顺序表是否为满了
    private boolean isFull() {
       /* if (this.usedSize == this.elem.length)
        {
            return true;//满了
        }
    return false;*///没有满
        return    this.elem.length == this.usedSize;
    }
    //在pos位置新增元素
    public void add(int pos, int data) {
        if (isFull()) {
           // this.elem = Arrays.copyOf(this.elem, this.elem.length*2);//增容申请新空间,拷贝数据,释放旧空间
            int[]   k= Arrays.copyOf( elem,elem.length*2);
              this.elem=k;
        }
        //pos位置是否合法
        if (pos < 0 || pos > this.elem.length) {
            /*System.out.println("插入的位置不合法");
       return;*/
            throw new IndexOutOfBoundsException("pos位值不合法");
        }
        //挪数据
        for (int i = usedSize - 1; i >= pos; i--) {
            elem[i + 1] = elem[i];
        }
//插入数据
        elem[pos] = data;
        usedSize++;
    }
    
  //判断是否包含某个元素
    public boolean contains(int toFind) {
        for (int x : this.elem) {
            if (this.elem[toFind] == x) {
                return true;//包含
            }
        }
        return false;//不包含
    }
  //判断顺序表是否为空
    private   boolean   isEmpty(){
        if(usedSize==0){
            return true;//为空
        }
        return false;//不为空
        //return  usedSize==0;
    }
    //判断某个元素对应的位置
    public int search(int toFind) {
        int m=0;
        if(isEmpty())
        {
            System.out.println("顺序表为空");
        } else {
            for (int i = 0; i <= this.usedSize - 1; i++)
                if (this.elem[i] == toFind)
                    return  i;
        }
        return -1;//没有找到
    }
  //获取pos位置的元素
    public int getPos(int pos) {
        if (pos < 0 || pos > this.elem.length) {
            return -1;
        }
        return this.elem[pos];
    } 
//给pos位置的元素设为value
public  void  setPos(int pos,int value){
    this.elem[pos]=value;
    System.out.println(this.elem[pos]);
}
//删除第一次出现的关键字
    public   void  remove(int toRemove){
        int  b=this.search(toRemove);
        if(b==-1){
          System.out.println("没有找到");
          return ;
      }
      //删除
          for(int i=b;i<usedSize-1;i++){
              elem[i]=elem[i+1];
          }
          usedSize--;
    }
   //获取顺序表的长度
    public  int  size( ){
        return   this.usedSize;
    }
 //清空顺序表
    public   void   clear(){
        this.usedSize=0;
    }

}

3.链表

链表是一种物理结构上非连续存储结构,数据元素的逻辑顺序是通过链表的引用链接次序实现的
有8中链表结构
在这里插入图片描述
//节点类
class ListNode{
public int data;
public ListNode next;//下一个节点
ListNode(int data){
this.data=data;
this.next=null;
}
}
//单链表类
class MySignalList {
public ListNode head;//头节点

MySignalList() {
    this.head = null;
}

//头插法
public void addFirst(int data) {
   ListNode     node=new ListNode(data);
   if(this.head==null){
      this.head=node;
   }else{
       node.next=head;
       head=node;
   }
}
//尾插法
public void addLast(int data) {
   ListNode  node=new ListNode(data);
   ListNode    cur=this.head;
   if(this.head==null){
       this.head=node;
   }
   while(cur.next!=null){
       cur=cur.next;
   }
   cur.next=node;
}
//单链表的长度
public int getLength()   {
    int count=0;
    ListNode  cur=head;
    while(cur!=null){//节点不为空
        count++;
        cur=cur.next;
    }
    return count;
}
//找cur-1的位置
private ListNode searchIndex(int index) {
        ListNode cur=head;
       int count=0;
        while(count<index-1){
            cur=cur.next;
            count++;
        }
        return   cur;
}

//任意位置插入,第一个节点为0号下标
public boolean addIndex(int index, int data) {

if(index<0||index>getLength()){
System.out.println(“插入位置不合法”);
return false;
}
if(index0){
addFirst(data);
return true;
}
//找到index-1 的位置
ListNode cur=searchIndex(index);
ListNode node =new ListNode(data);
//插入节点
node.next=cur.next;
cur.next=node;
return true;
}
//疑问
//查找关键字key是否在单链表中
public boolean contains(int key) {
ListNode cur=this.head;
while(cur!=null){
if(cur.data
key){
return true;
}
cur=cur.next;
}
return false;
}
public void display() {
ListNode cur = this.head;
while (cur != null) {
System.out.print(cur.data+" ");
cur = cur.next;
}
System.out.println();
}

//找到key的前驱
private ListNode searchPrev(int key) {
       ListNode   cur=this.head;
       while( cur.next!=null){
               if(cur.next.data==key){
                   return  cur;
               }
               cur=cur.next;
       }
       return null;
}
//删除第一次出现关键字为key 的节点
public void remove(int key) {
    //判断是否为空链表
    if (this.head == null) {
        System.out.println("单链表为空");
    }
    //删除的节点为头节点
    if (this.head.data == key) {
        this.head = this.head.next;
        return;
    }
    ListNode cur = searchPrev(key);
    ListNode del = cur.next;
    //删除
    cur.next = del.next;
}

//删除所有关键字为key的节点
public void removeKey(int key) {
if(this.head.datakey){
this.head=this.head.next;
return ;
}
ListNode cur=this.head;
ListNode pre=this.head.next;
while(cur.next!=null){//不能写成 cur,要不if语句会出现空指针异常
if(cur.next.data
key){
cur.next=pre.next;
//pre=pre.next;
}else{
cur=pre;
pre=pre.next;
}
}
}

//头插法
//prev  重点   反转
//在反转前一定要保存下一个节点 
public ListNode reverseList() {
    ListNode prev = null;//前一个节点
     ListNode newHead=null;
    ListNode cur = this.head;//头节点
     while (cur!= null) {
        ListNode curNext = cur.next;//保留下一个节点
        if (curNext == null) {
             newHead = cur;
        }
        cur.next = prev;//指针反转
        prev = cur;//前节点后移
        cur = curNext;//当前节点后移
    }
    return newHead; 
}
public void display1(ListNode newHead) {
    ListNode cur = newHead;
    while (cur!= null) {
        System.out.print(cur.data + "  ");
        cur = cur.next;
    }
    Sy stem.out.println();
}

//输出中间节点 当链表为偶数的时候,返回两个节点中前一个节点;
//1.用两个指针遍历单链表,一个快指针,一个慢指针
//2.快指针每次向前移动两个节点,慢指针向前移动一个节点
//3.当快指针移动到链表结尾的时候,慢指针所在的位置就是中间节点的位置
public ListNode middleNode() {
ListNode fast = this.head;
ListNode slow = this.head;
while (fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;
}
return slow;
}
//输入一个链表,输出倒数第k个节点
//两个指针,第一个节点向前移动k-1次,之后两个节点共同移动
//当前面的指针到达末尾的时候,后面的指针所在的位置就是倒数第k个节点
public ListNode m(int k) {
if (k < 0 || k > getLength()) {
System.out.println(" k不合法");
}
ListNode fast = this.head;
ListNode slow = this.head;
while (k - 1 > 0) {//前移k-1步
if (fast.next != null) {
fast = fast.next;
k–;
}//else{
//System.out.println(“没有这个节点”);
}
while (fast.next != null) {//共同移动
fast = fast.next;
slow = slow.next;
}
return slow;
}

}
//以x为基准将单链表分开成两部分
public ListNode partition(int x) {
ListNode cur = this.head;
ListNode beforeStart = null;
ListNode beforeEnd = null;
ListNode afterStart = null;
ListNode afterEnd = null;
while (cur != null) {//遍历单链表
/ListNode curNext = c ur.next;
cur.next = null;
/
if (cur.data < x) {
if (beforeStart == null) {
beforeStart = cur;
beforeEnd = beforeStart;
} else {
beforeEnd.next = cur;
beforeEnd = beforeEnd.next;
}
} else {
if (afterStart == null) {
afterStart = cur;
afterEnd = afterStart;
} else {
afterEnd.next = cur;
afterEnd = afterEnd.next;
}
}
cur = cur.next;
}
if (beforeStart == null) {
return afterStart;
}
beforeEnd.next = afterStart;
if (afterStart != null) {
afterEnd.next = null;
}
return beforeStart;
}

//删除重复节点
public ListNode deleteDuplication() {
    ListNode node = new ListNode(-1);//虚拟节点
    ListNode cur = this.head;
    ListNode tmp = node;
    while (cur != null) {
        if (cur.next != null && cur.data == cur.next.data) {
            while (cur.next != null && cur.data == cur.next.data) {//cur要多走一步
                cur = cur.next;
            }
            cur = cur.next;
        } else {
            tmp.next = cur;// 没有重复的节点
            cur = cur.next;
            tmp = tmp.next;
        }
    }
    temp.next=null;

return node.next;
}

//回文结构
public boolean chkPalindrome() {
    ListNode fast = this.head;
    ListNode slow = this.head;
 while (fast != null && fast.next != null) {//找到中间节点
        slow = slow.next;
        fast = fast.next.next;
    }
    //反转
    ListNode p = slow.next;
    while (p != null) {
        ListNode pNext = p.next;
        p.next = slow;
        slow = p;
        p = pNext;
    }
    while (slow != this.head) {
        if (slow.data != head.data) {
            return false;
        }
        if (this.head == slow) {
            return true;
        }
        slow = slow.next;
        head = head.next;

    }
    return true;
}

//判断是否有环 
public boolean hasCycle() {
    ListNode fast = this.head;
    ListNode slow = this.head;
    while (fast != null && fast.next != null) {
        fast = fast.next.next;//fast走两步
        slow = slow.next;//slow走一步
        if (slow == fast) {
            break;
        }
    }
    if (fast == null || fast.next == null) {//没有环
        return false;
    }
    return true;
}

//环
public void createLoop() {
    ListNode cur = this.head;
    while (cur.next != null) {
        cur = cur.next;
    }
    cur.next=this.head.next;
}

//找到环的入口    slow=this.head;  slow=slow.next;   fast=fast.next;
public ListNode detectCycle() {
    ListNode fast = this.head;
    ListNode slow = this.head;
    while (fast != null && fast.next != null) {
        fast = fast.next.next;
        slow = slow.next;
        if (slow == fast) {
            break;
        }
    }
    if (fast == null || fast.next == null) {//没有环
        return null;
    }
    slow = this.head;
    while (slow != fast) {
        slow = slow.next;
        fast = fast.next;
    }
    return fast;
}

//
public int listen() {
if(head==null){
return -1;
}
ListNode fast = this.head;
ListNode slow = this.head;
while (fast != null && fast.next != null) {
fast = fast.next.next;
slow = slow.next;
if (slow == fast) {
break;
}
}
if (fast == null || fast.next == null) {//没有环
return -1;
}
int count=1;
slow=slow.next;
while (slow != fast) {
slow = slow.next;
count++;

    }
    return  count ;
}

}

public class Test1 {
public static void main(String[] args) {
MySignalList mySignalList=new MySignalList();
mySignalList.addIndex(0,12);
mySignalList.addIndex(1,13);
mySignalList.addIndex(2,17);
mySignalList.addIndex(3,13);
mySignalList.addIndex(0, 12);
/* MySignalList pL = new MySignalList();
pL.addLast(12);
pL.addLast(13);
pL.addLast(14);
pL.addLast(15);
MySignalList pS = new MySignalList();
pS.addLast(12);
pS.addLast(12);
pS.addLast(12);
pS.addLast(12);*/
//mySignalList.contains(19);
// mySignalList.remove(13);
// mySignalList.display ();
// mySignalList.removeKey(13);
mySignalList.display();
mySignalList.middleNode();

    // ListNode  newHead=mySignalList.reverseList();
    //mySignalList.display1( newHead);
    // ListNode node= mySignalList.partition(13);
    //mySignalList.display1(node);
    // ListNode   node1= mySignalList.deleteDuplication();
    //mySignalList.display1(node1);
    //mySignalList.chkPalindrome();
    //mySignalList.createLoop();
    //mySignalList.hasCycle();
    //mySignalList.detectCycle();
    // mySignalList.listen();
}

//相交
public static ListNode getIntersection(ListNode headA, ListNode headB) {
    if (headA == null || headB == null) {
        return null;
    }
    //永远指向最远的单链表
    ListNode pL = headA;
    //永远指向最短的单链表
    ListNode pS = headB;
    int lenA = 0;
    int lenB = 0;
    //分别求长度
    while (pL != null) {
        pL = pL.next;
        lenA++;
    }
    while (pS != null) {
        pS = pS.next;
        lenB++;
    }
    //求长度的差值
    int len = lenA - lenB;
    if (len < 0) {
        pL = headB;
        pS = headA;
        len = lenB - lenA;
    }
    while (len > 0) {
        pL = pL.next;
        len--;
    }
    //走完len之后两个开始同时走
    //一直走直到next相同就是节点
    while (pL != pS && pL != null) {
        pL = pL.next;
        pS = pS.next;
    }
    if (pL == pS && pS != null) {
        return pL;
    }
    return  null;
      /* while(pL.next!=pS.next){
           pL=pL.next;
           pS=pS.next;
       }*/

    //万一没有相交,并且两个单链表长度一样
    //防止最后一个节点
    /*if (pL.next == pS.next && pL.next != null) {
        return  pL.next;
    }
    return null;*/
}
public void createCut(ListNode headA, ListNode headB) {
    headA.next.next= headB.next.next.next;
}

//合并两个有序的单链表
public ListNode mergeTowLists(ListNode headA, ListNode headB) {
//curA curB
ListNode node = new ListNode(-1);
ListNode tmp = node;
while (headA != null && headB != null) {
if (headA.data < headB.data) {
tmp.next = headA;
headA = headA.next;
tmp = tmp.next;
} else {
tmp.next = headB;
headB = headB.next;
tmp = tmp.next;
}
}
if (headA != null) {
tmp.next = headA;
}
if (headB != null) {
tmp.next = headB;
}
return node.next;
}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值