数据结构-单链表

(1)链表是以节点的方式来存储,是链式存储
(2)每个节点包含data域,next域:指向下一个节点
(3)链表的各个节点不一定是连续存储
(4)链表分为带头节点的链表和没有头节点的链表,根据实际的需求来确定

1、使用带head头的单向链表实现,对水浒传人物的增删改查操作。
(1)添加元素,直接添加至链表尾部
添加(创建)
先创建一个head头节点,作用就是表示单链表的头(不存放具体的数据)
后面我们每添加一个节点,就直接加入到链表的最后
遍历
* 通过一个辅助变量遍历*

(2)添加元素,按照no顺序
首先找到新添加的节点的位置,是通过辅助变量(指针),通过遍历来搞定
新的节点.next=temp.next;
将 temp.next=新的节点

在这里插入图片描述

(3)修改节点
先找到节点,通过遍历
temp.name=newHerNode.name;
temp.nikname=newHerNode.nikname;

(4)删除节点
从单链表中删除一个节点的思路
先找到需要删除的这个节点的前一个节点temp
temp.next=temp.next.next;
被删除的节点,将不会有其他引用指向,会被垃圾回收机制回收

package database;

public class SingleLinkedListDemo {
    public static void main(String[] args) {
        HeroNode heroNode1=  new HeroNode(1,"松江","及时雨");
        HeroNode heroNode2=  new HeroNode(2,"卢俊义","玉麒麟");
        HeroNode heroNode3=  new HeroNode(3,"吴勇","智多星");

      SingleLinkedList s =  new SingleLinkedList();
     /*    s.add(heroNode1);
        s.add(heroNode3);
        s.add(heroNode2);*/

        //按顺序排序
        s.addByOrder(heroNode1);
        s.addByOrder(heroNode3);
        s.addByOrder(heroNode2);

      //列出数据
        s.list();
        System.out.println("---------------");
        //更新数据
        HeroNode newHeroNode =new HeroNode(2,"周瑜","黑旋风");
        s.update(newHeroNode);
        s.list();

        //删除节点
        System.out.println("---------------------------");
        s.del(3);
        s.list();
    }
}
class SingleLinkedList{
    private HeroNode head =new HeroNode(0,"","");
    //返回头结点
    public HeroNode gethead(){
        return head;
    }
    //添加节点在链表尾部
    public void add(HeroNode heroNode){
        HeroNode temp=head;
        //遍历链表
        while (true){
            if (temp.next==null){
                break;
            }
            temp =temp.next;
        }
        temp.next=heroNode;
    }
    //添加英雄,按照顺序
    public void addByOrder(HeroNode heroNode){
        HeroNode temp=head;
        boolean falg=false;
        while (true){
            if (temp.next==null){
               // System.out.println("数组为空");
                break;
            }
            if (temp.next.no> heroNode.no){
                break;
            }
            if (temp.next.no==heroNode.no){
                System.out.println("已经存在");
                falg=true;
            }
            temp=temp.next;
        }

        if (falg){
            System.out.println("数组已满");
        }else {
            heroNode.next=temp.next;
            temp.next=heroNode;
        }
    }
    //修改名字,昵称,根据no修改,且no不能改变
    public void update(HeroNode newHeroNode){
        if (head.next==null){
            System.out.println("已到数组最后");
            return;
        }
        HeroNode temp =head.next;
        boolean flag=false;
        while (true){
            if (temp==null){
                System.out.println("修改的数组为空");
                break;
            }
            if (temp.no== newHeroNode.no){
                //找到修改节点
                flag=true;
                break;
            }
            temp=temp.next;
        }
        if (flag){
            temp.name=newHeroNode.name;
            temp.nikname=newHeroNode.nikname;
        }else {
            //没找到修改的节点
            System.out.println("未找到对应的节点");
        }

    }
    //删除节点
    public  void del(int no){
        HeroNode temp=head;
        boolean flag=false;
        while (true){
            if (temp.next==null){
                System.out.println("已经遍历完最后一个节点,删除节点为空");
                break;
            }
            if (temp.next.no==no){
                flag=true;
                break;
            }
            temp=temp.next;
        }
        if (flag){
            temp.next=temp.next.next;
        }
    }
    //显示遍历
    public void list(){
        //判断是否为空
        if (head.next==null){
            System.out.println("链表为空");
            return;
        }
        HeroNode temp=head.next;
        while (true){
            if (temp==null){
                break;
            }

            System.out.println(temp);
            temp=temp.next;
        }
    }
}
class HeroNode{

    public int no;
    public String name;
    public String nikname;
    public HeroNode next;

    //构造器
    public HeroNode(int no, String name, String nikname){
        this.no=no;
        this.name=name;
        this.nikname=nikname;
    }

    @Override
    public String toString() {
        return "HeroNode{" +
                "no=" + no +
                ", name='" + name + '\'' +
                ", nikname='" + nikname + '\'' +
                '}';
    }
}

在这里插入图片描述
单链表一些题

(1)求单链表中有效节点的个数

 //单链表中获得有效节点个数(存放数据的节点) ,不包含头节点
    //return 返回有效节点数
    public static int getLength(HeroNode head) {
        if (head == null) {
            return 0;
        }
        int length = 0;
        HeroNode cur = head.next;
        while (cur != null) {
            length++;
            cur = cur.next;  //遍历
        }
        return length;
    }

(2)查找单链表中的倒数第k个结点 【新浪面试题】

    //寻找单链表中的倒数第k个节点
    public static HeroNode findlastindex(HeroNode head, int index) {
        //判断链表是否为空
        if (head.next == null) {
            //有一个头节点的空链表
            return null;
        }
        //第一遍遍历,得到数组长度
        int size = getLength(head);  
        //第二遍遍历,对size-index 要求
        if (index > size || index <= 0) {
            return null;
        }
        //for循环遍历
        HeroNode cur = head.next;
        for (int i = 0; i < size - index; i++) {
            cur = cur.next;
        }
        return cur;
    }

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode getKthFromEnd(ListNode head, int k) {
          if(head==null){
            return null;
        }
        int n=0;  //循环查看有多少个节点
        ListNode curhead = head;
        while(curhead!=null){
            n++;
            curhead=curhead.next;
        }
        int index=n-k;
        if(index<0||k>n){
            return null;
        }
        curhead=head;
        for(int i=0;i<index;i++){
            curhead=curhead.next;
        }
        return curhead;
    }
}

(3)单链表的反转【腾讯面试题,有点难度】

    //实现单链表反转
    public static void reversedlist(HeroNode head){
        if ((head.next==null)||(head.next.next==null)){
            return;//为空链表或者为只有一个节点的链表
        }
        //定义一个辅助的指针
        HeroNode cur =head.next;
        HeroNode next =null;
        HeroNode reversedhead =new HeroNode(0,"","");
        //遍历链表herohead
        while (cur!=null){
            next =cur.next;
            cur.next=reversedhead.next;
            reversedhead.next=cur;
            cur=next;
        }
        head.next=reversedhead.next;

    }

(4)从尾到头打印单链表 【百度,要求方式1:反向遍历 。 方式2:Stack栈】

    //用栈反转链表
    public  static  void reversestack(HeroNode head){
        if (head.next==null){
            return;
        }
        Stack<HeroNode> stack = new Stack<HeroNode>();
        HeroNode cur=head.next;
        while (cur!=null){
            stack.push(cur);
            cur=cur.next;
        }
        while (stack.size()>0){
            System.out.println( stack.pop());
        }
    }
/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode reverseList(ListNode head) {
 if (head==null){
                    return null;
                }
        Stack<ListNode> stack =new Stack<>();
          ListNode cur=head;
      
          while (cur!=null){
              stack.push(cur);
              cur=cur.next;
          }
            ListNode res=  stack.pop();
        ListNode node=res;
          while (stack.size()>0){
            node.next=  stack.pop();
            node=node.next;
          }
          node.next=null;
     return res;
    }
}

(5)合并两个有序的单链表,合并之后的链表依然有序【课后练习.】

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        ListNode lN=new ListNode(0);//指针不存放实际数据
        ListNode cur=lN;
        while (l1!=null&&l2!=null){
           if (l1.val<l2.val){
               cur.next=l1;
               cur =cur.next;
               l1=l1.next;
           }else {
               cur.next=l2;
               cur=cur.next;
               l2=l2.next;
           }
        }
        if (l1==null){
            cur.next= l2;
        }else {
            cur.next=l1;
        }
        return lN.next;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值