精华内容
下载资源
问答
  • 有序链表

    2016-09-05 22:44:46
    链表中有时候需要对数据的顺序有所要求,对于一些应用来说链表中保持数据有序是有意义的一件事,下面就围绕有序链表,说明有序链表的创建和利用链表实现排序。 在有序链表插入一个数据项,可以采用之前的插入排序的...

           链表中有时候需要对数据的顺序有所要求,对于一些应用来说链表中保持数据有序是有意义的一件事,下面就围绕有序链表,说明有序链表的创建和利用链表实现排序。

          在有序链表插入一个数据项,可以采用之前的插入排序的思想,通过局部有序实现数据的排序。插入数据通常在链表中有三种方式:在链表头部、尾部、中间。这三种方式需要考虑到。

    有序链表的创建过程

           和一般链表创建一样,首先创建一个结点node,包括一个自身的引用。

    class Link3
    {
        public int data;
        Link3 next;
        public Link3(int data)
        {
            this.data=data;
        }
        public void showData()
        {
            System.out.println("data "+data);
        }
    }

           链表添加数据需要考虑几种不同情况,可以将在中间插入数据和链表尾部插入数据归为一类,在表头插入数据是另外一类;

    public void add( int key)
        {
            Link3 newNode=new Link3(key);
            //先向链表中添加数据,再进行排序
            Link3 privious=null;
            Link3 current=first;
            while(current!=null&&current.data<key)//指针后移
            {
                privious=current;
                current=current.next;   
            }
            if(privious==null)//如果数据再链表头部插入
            {
                first=newNode;
            }
            //如果不是在链表头部插入
            else
            {
                //newNode=privious;
                privious.next=newNode;
            }
            newNode.next=current;   
        }

           添加一个Node主要是两个步骤,将前一个节点的自引用指向该节点,另外该节点的自引用指向下一个节点。引入privious是为了找到上一个节点和要指向的下一个节点。

    privious=current;
    current=current.next;

           这是根据数据大小从前向后搜索。除此之外就是常见链表的删除数据和显示操作了。

    public Link3 remove()
        {
            Link3 temp=first;
            first=first.next;
            return temp;
        }
    public void showList()
        {
            Link3 current=first;
            while(current!=null)
            {
               current.showData();
               current=current.next;
            }
        }

    测试及测试结果:

            SortLinkList linklist=new SortLinkList();
            linklist.add(1);
            linklist.add(2);
            linklist.add(3);
            linklist.add(4);
            linklist.add(8);
            linklist.add(7);
            linklist.add(6);
            linklist.add(5);
            linklist.showList();
            linklist.remove();
            linklist.remove();
            linklist.showList();
    data 1
    data 2
    data 3
    data 4
    data 5
    data 6
    data 7
    data 8
    data 3
    data 4
    data 5
    data 6
    data 7
    data 8

    有序链表的效率

          有序链表插入和删除某一项最多需要O(N)次比较,但是可以在O(1)时间内删除内找到或删除最小值,因为其总在链表头部。链表可以用于一种高效的排序机制。假设有一个无序数组,如果从这个数组中取出数据,之后将数据插入链表并同时进行插入排序,之后将数据从链表中删除,更新到数组中,这样数组就可以排好序了。这样排序的方式比传统的插入排序要好一些,因为少了一些复制。

    这里写图片描述

    下面给出以上示意图的实现代码:

    public class SortLinkListArrayApp {
    
        /**
         * @param args
         */
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            int size=8;
            Link4[] linkArray=new Link4[size];
            for(int j=0;j<size;j++)
            {
                 int n=(int)(Math.random()*10);
                 Link4 newNode=new Link4(n);
                 linkArray[j]=newNode;  
            }
            //输出排序之前的数组
            System.out.println("排序之前的数据:");
            for(int k=0;k<size;k++)
            {
                linkArray[k].showData();
            }
            //排序
            SortLinkListArray sortLink=new SortLinkListArray(linkArray);
            //将排序后的数据存入Link数组,更新数据
            for(int m=0;m<size;m++)
            {
                linkArray[m]=sortLink.remove();
            }
            //输出排序后的数组
            System.out.println("排序之后的数据:");
            for(int n=0;n<size;n++)
            {
                //System.out.println(linkArray[n].data);
                linkArray[n].showData();
            }
    
        }
    
    }
    class Link4
    {
        public int data;
        Link4 next;
        public Link4(int data)
        {
            this.data=data;
        }
        public void showData()
        {
            System.out.println("data "+data);
    
        }
    }
    class SortLinkListArray
    {
        Link4 first;
        //此处通过构造函数进行排序 Link数组作为参数进行传递
        public SortLinkListArray(Link4[] linkArr)
        {
            first=null;
            for(int i=0;i<linkArr.length;i++)
            {
                this.add(linkArr[i].data);
            }
        }
        public void add( int key)
        {
            Link4 newNode=new Link4(key);
            //先向链表中添加数据,再进行排序
            Link4 privious=null;
            Link4 current=first;
            while(current!=null&&current.data<key)//指针后移
            {
                privious=current;
                current=current.next;   
            }
            if(privious==null)//如果数据再链表头部插入
            {
                first=newNode;
            }
            //如果不是在链表头部插入
            else
            {
                //newNode=privious;
                privious.next=newNode;
            }
            newNode.next=current;
    
        }
        public Link4 remove()
        {
            Link4 temp=first;
            first=first.next;
            return temp;
        }
        public void showList()
        {
            Link4 current=first;
            while(current!=null)
            {
               current.showData();
               current=current.next;
            }
        }
    }

    以下是测试结果:

    排序之前的数据:
    data 2
    data 2
    data 4
    data 9
    data 1
    data 3
    data 2
    data 1
    排序之后的数据:
    data 1
    data 1
    data 2
    data 2
    data 2
    data 3
    data 4
    data 9

          每次输入数据不同,因此排序输出也不相同。但是也需要考虑这种排序的劣势:在排序时内存中会同时存在数组和链表。开辟的内存差不多两倍内存大小。但是有现成的有序链表类可用,利用该链表来进行插入排序对不太大的数组排序还是比较便利。

    展开全文
  • 本文是关于如何将两个有序链表并为一个有序链表
  • 何将两个有序链表并为一个有序链表
  • 两个有序链表,合成为一个有序链表。文档中为升序模式。如果有需要的朋友们可以参考下代码。时间复杂度m+n,空间复杂度为2(m+n)
  • C++版本将两个有序链表合并为一个新的有序链表并返回原理及代码实现
  • 两个有序链表合并成一个有序链表

    千次阅读 2019-04-17 14:04:04
    算法:两个有序链表合并成一个有序链表(Java实现) 首先我们创建链表的结构类 @Getter @Setter class Node{ private Integer data; //存储数据 private Node next; //后继引用 public Node(Integer data) { ...

    算法:两个有序链表合并成一个有序链表(Java实现)
    首先我们创建链表的结构类

    @Getter
    @Setter
    class Node{
        private Integer data;   //存储数据
        private Node next;   //后继引用
        public Node(Integer data) {
            this.data = data;
        }
    }
    

    准备数据:

    	//准备第一个有序链表
    Node readyNode1(){
        Node node = new Node(1);
        Node node1 = new Node(6);
        Node node2 = new Node(9);
        Node node3 = new Node(10);
        node.next = node1;
        node1.next = node2;
        node2.next = node3;
        return node;
    }
    
    //准备第二个有序链表
    Node readyNode2(){
        Node node = new Node(2);
        Node node1 = new Node(3);
        Node node2 = new Node(8);
        Node node3 = new Node(14);
        Node node4 = new Node(22);
        node.next = node1;
        node1.next = node2;
        node2.next = node3;
        node3.next = node4;
        return node;
    }
    

    我们想要实现链表的合并排列。
    1.就要新建一个链表;
    2.然后依次比较初始链表的大小;把数值小的放到新链表中,注意:只能放链表的值,不能放后继指针。
    3.每次在新链表中插入数据的时候,都要保证插入的数据是在新链表的最后一个节点上。
    代码如下:

    //合并两个有序链表
    public Node hebing(Node node1, Node node2){
    	 if (node1 == null)   return node2;
         if (node2 == null)   return node1;
        
        Node node3 = null;       //递归合并两个有序链表   
        while(node1 != null || node2 != null) {
            Node n = new Node();    //每次循环使用一个Node去存储数据
            if (node1 == null) {
                getLastNode(node3).next = node2;
                break;
            } else if (node2 == null) {
                getLastNode(node3).next = node1;
                break;
            } else if (node1.data > node2.data) {
                n.data = node2.data;
                node2 = node2.next;
            } else if (node1.data <= node2.data) {
                n.data = node1.data;
                node1 = node1.next;
            }
    
            if (node3 == null) {
                node3 = n;
            } else {
                getLastNode(node3).next = n;
            }
    
        }
        return node3;
    }
    
    /**
     * 获取链表的最后一级
     */
    public Node getLastNode(Node node){
        while (node != null){
            if (node.next == null) {
                return node;
            } else {
                node = node.next;
            }
        }
        return null;
    }
    

    测试

    @Test
    public void run(){
        Node node1 = readyNode1();
        Node node2 = readyNode2();
        Node hebing = hebing(node1, node2);
        System.out.println(JSONObject.toJSONString(hebing));
    }
    

    输出结果:

    		{"data":1,"next":{"data":2,"next":{"data":3,"next":{"data":6,"next":{"data":8,"next":{"data":9,"next":{"data":10,"next":{"data":14,"next":{"data":22}}}}}}}}}
    
    展开全文
  • 已知两个有序链表,将两个有序链表融合成一个有序链表的实现方法: #include using namespace std; typedef struct _listNode { int data; struct _listNode *next; }listNode; void printList(listNode *...

    已知两个有序链表,将两个有序链表融合成一个有序链表的实现方法:

    #include <iostream>
    using namespace std;
    
    typedef struct _listNode
    {
    	int data;
    	struct _listNode *next;
    }listNode;
    
    void printList(listNode *plist)
    {
    	if(plist == NULL)
    		return;
    
    	listNode *tlist = plist;
    
    	while(tlist != NULL)
    	{
    		cout << tlist->data << "\t";
    		tlist = tlist->next;
    	}
    	cout << endl;
    }
    
    listNode *listNodeMerge(listNode *p1ist1, listNode *p1ist2)
    {
    	listNode *p1 = p1ist1;
    	listNode *p2 = p1ist2;
    	listNode *pcurr = NULL;
    	listNode *pHead = NULL;
    	listNode *pt = NULL;
    
    	//先判断链表是否为空
    	if(p1 == NULL && p2 != NULL)
    		return p2;
    	else if(p1 != NULL && p2 == NULL)
    		return p1;
    	else if(p1 == NULL && p2 == NULL)
    		return NULL;
    
    	//首先选择一个头节点
    	if(p1->data < p2->data)
    	{
    		pHead = p1;
    		p1 = p1->next;
    	}
    	else
    	{
    		pHead = p2;
    		p2 = p2->next;
    	}
    
    	pcurr = pHead; //辅助指针
    
    	while(p1 != NULL && p2 != NULL)
    	{
    		if(p1->data < p2->data)
    		{
    			pt = p1;
    			p1 = p1->next;
    		}
    		else
    		{
    			pt = p2;
    			p2 = p2->next;
    		}
    
    		pcurr->next = pt;
    		pcurr = pcurr->next;
    	}
    
    	if(p1 != NULL) //其中有一个链表已经指向NULL,而另一个还没有指向NULL
    		pcurr->next = p1;
    	else
    		pcurr->next = p2;
    
    	return pHead;
    }
    
    int main()
    {
    	//为方便先定义两个有序链表,也可用new(malloc)的方式生成链表
    	listNode n1,n3,n5;
    	listNode n2,n4,n6,n7;
    
    	n1.data = 1, n1.next = &n3;
    	n3.data = 2, n3.next = &n5;
    	n5.data = 3, n5.next = NULL;
    
    	n2.data = 0, n2.next = &n4;
    	n4.data = 4, n4.next = &n6;
    	n6.data = 6, n6.next = &n7;
    	n7.data = 9, n7.next = NULL;
    
    	listNode *p1 = &n1;
    	listNode *p2 = &n2;
    
    	//打印该链表
    	cout << "list1:\n";
    	printList(p1);
    	cout << "list2:\n";
    	printList(p2);
    
    	//打印融合后的链表
    	cout << "After merge list:\n";
    	listNode *pnew = listNodeMerge(p1, p2);
    
    	printList(pnew);
    
    	return 0;
    }


    展开全文
  • 多个有序链表合并成一个有序链表的C++递归实现 主体思想: 1.多个有序链表看成是一个二维链表,此二维链表在 y 轴方向是有序的,x轴方向是无序的 2.在x 轴方向(x=0),找出此维度最小的元素(可以输出了), 3....

     多个有序链表合并成一个有序链表的C++递归实现

    主体思想:

    1.多个有序链表看成是一个二维链表,此二维链表在 y 轴方向是有序的,x轴方向是无序的

    2.在x 轴方向(x=0),找出此维度最小的元素(可以输出了),

    3.将此元素置于x 轴最大的地方,重新将 y=x 的这一条有序链表 沿 y 轴方向移动 -1 (当此链表没有元素 存在 y>= 0了,删除此一维链表).

    4.重复在 x=0 这一层找到最小的元素,重复 3、4 。(可以递归了)

    手动图片讲述,小节点内有数字,1是初始状态,2\3循环,(2的过程在 FindMin() 中,图片简化过程)

    注意:

    1.递归的判断条件  --  二维链表是否为空

    2.初始化 vector 的时候,请注意不要仅初始化 vector <ListNode*> *   , 这个是仅初始化了一个指针,并没有初始化 vector ,我花了很久来调这个较低级的错误。

    3.创建基础数据的时候(create()),即二维链表,注意别打错字,链表出了循环,将会溢栈,很莫名也不好找的错误。

    // MergeList.cpp: 定义控制台应用程序的入口点。
    //
    
    #include "stdafx.h"
    
    #include<iostream>
    #include<algorithm>
    #include<string>
    #include<vector>
    
    using namespace std;
    
    typedef struct ListNode {
    	int item;
    	struct ListNode * next = NULL;
    };
    
    class MergeList
    {
    
    public:
    	//lists 直接记录每一个链表第一个节点
    	bool mergeKLists(vector<ListNode*>* lists, ListNode * mergeHead)//使用vector<ListNode*>地址,可以直接对vector进行修改
    	{
    		if (lists->size() == 0) //List 中一个元素都没了,排序结束
    			return false;	
    
    		mergeHead->next = FindMin(lists); //mergeHead 记录最小值
    		lists->pop_back(); //先删除最小的一个
    
    		//如果list 中最小的一个 元素不是这个链表中的尾节点,再在链表最末端加上其下一个元素地址,即 mergeHead->next->next
    		if (mergeHead->next->next != NULL) 
    			lists->push_back(mergeHead->next->next);
    
    		//在mergeHead 添加完一个元素后,继续寻找下一个元素
    		mergeKLists(lists, mergeHead->next);
    
    		return false;
    	}
    
    private:
    	//优化冒泡,返回最小的节点,进行添加(链表排序用归并,代码较多,太繁琐了),并把最小节点放到vector末尾。
    	ListNode * FindMin(vector<ListNode*>* lists)
    	{
    		int num = lists->size();
    		for (int i = 0; i < num - 1; i++)//数组下标
    		{
    			if (lists->at(i)->item < lists->at(i + 1)->item)
    				swap(lists->at(i), lists->at(i + 1)); //小的沉底
    		}
    		return lists->at(num-1);
    	}
    
    	
    };
    //创建测试数据
    void create(vector<ListNode *> * lists);
    
    int main()
    {
    	ListNode * mergeHead = new ListNode;  mergeHead->item = -1;
    	vector<ListNode *> LLists;
    	MergeList mergeList ;
    
    	//创建二维链表
    	create(&LLists);
    	//进行多链表合并
    	mergeList.mergeKLists(&LLists, mergeHead);
    	
    	//输出打印链表
    		while (mergeHead->next != NULL)
    		{
    			mergeHead = mergeHead->next;
    			cout << mergeHead->item << endl;
    		}
    
    		getchar();
    	return 0;
    }
    
    void create (vector<ListNode *> * lists)
    {
    	ListNode *a1, *a2, *a3, *a4, *a5;
    	ListNode *b1, *b2, *b3;
    	ListNode *c1, *c2, *c3, *c4;
    	ListNode *d1, *d2, *d3;
    	ListNode *e1, *e2, *e3, *e4;
    
    	//创建链表 a1
    	a5 = new ListNode;
    	a5->item = 87; a5->next = NULL;
    	a4 = new ListNode;
    	a4->item = 46; a4->next = a5;
    	a3 = new ListNode;
    	a3->item = 39; a3->next = a4;
    	a2 = new ListNode;
    	a2->item = 28; a2->next = a3;
    	a1 = new ListNode;
    	a1->item = 1; a1->next = a2;
    
    	//创建链表 b1
    	b3 = new ListNode;
    	b3->item = 10; b3->next = NULL;
    	b2 = new ListNode;
    	b2->item = 7; b2->next = b3;
    	b1 = new ListNode;
    	b1->item = 2; b1->next = b2;
    
    	//创建链表 c1
    	c4 = new ListNode;
    	c4->item = 28; c4->next = NULL;
    	c3 = new ListNode;
    	c3->item = 19; c3->next = c4;
    	c2 = new ListNode;
    	c2->item = 8; c2->next = c3;
    	c1 = new ListNode;
    	c1->item = 6; c1->next = c2;
    
    	//创建链表 d1
    	d3 = new ListNode;
    	d3->item = 80; d3->next = NULL;
    	d2 = new ListNode;
    	d2->item = 27; d2->next = d3;
    	d1 = new ListNode;
    	d1->item = 4; d1->next = d2;
    
    	//创建链表 e1
    	e4 = new ListNode;
    	e4->item = 60; e4->next = NULL;
    	e3 = new ListNode;
    	e3->item = 47; e3->next = e4;
    	e2 = new ListNode;
    	e2->item = 42; e2->next = e3;
    	e1 = new ListNode;
    	e1->item = 37; e1->next = e2;
    
    	lists->push_back(a1);
    	lists->push_back(b1);
    	lists->push_back(c1);
    	lists->push_back(d1);
    	lists->push_back(e1);
    }

    代码运行结果截图:

    展开全文
  • 1.算法:合并两个有序链表 将两个有序链表合并为一个新的有序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 2.解法 /** * Definition for singly-linked list. * public class ...
  • 将两个有序链表合并为一个有序链表 思路: 1.必须保证两个链表为有序链表 2.在两个链表都不为空的条件下,设一个 last=null; (1)如果链表1的值小于等于链表2的值,进行循环,先放链表1的值到新链表result,...
  • java中将两个有序链表合并为一个有序链表: 1.必须保证两个链表为有序链表 2.在两个链表都不为空的条件下,设一个 last=null; (1)如果链表1的值小于等于链表2的值,进行循环,先放链表1的值到新链表result,...
  • /* 链表操作:反转链表 合并两个有序链表 合并 K个有序链表 */ #include <stdio.h> #include <stdlib.h> #define _DEBUG #undef PDEBUG #ifdef _DEBUG #define PDEBUG(fmt, args...) printf(.....
  • """将两个有序链表合并为一个新的有序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例: 输入:1->2->4, 1->3->4 输出:1->1->2->3->4->4 """ 链表结构: ...
  • 将两个有序链表重新排序,合并为一个新的有序链表并返回 //将两个有序链表合并为一个新的有序链表并返回 public ListNode mergeTwoLists(ListNode l1, ListNode l2) { if (l1 == null) { //链表是否1为null ...
  • 数据结构合并两个递增的有序链表LA,LB形成新的有序链表LC
  • 利用递归法将两有序链表合并成链表,且合并后的链表仍然有序。 比较链表1和链表2的第一个结点数据,如果head1.data&lt;head2.data,则把结果链表头指向链表1的第一个结点。 对剩余的head1.next和链表2再次递归...
  • 将两个有序链表合并为一个新的有序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 题目来源:(LeetCode):https://leetcode-cn.com/problems/merge-two-sorted-lists 示例: 输入:1->2->4,...
  • 链表——有序链表的建立

    千次阅读 2018-08-13 10:20:12
    数据结构实验之链表六:有序链表的建立 Time Limit: 1000 ms Memory Limit: 65536 KiB Problem Description 输入N个无序的整数,建立一个有序链表,链表中的结点按照数值非降序排列,输出该有序链表。 ...
  • 题目:将两个有序链表合并为一个新的有序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例: 输入:1->2->4, 1->3->4 输出:1->1->2->3->4->4 思路: 递归 终止条件...
  • 链表之有序链表

    2013-08-06 22:27:17
    一般说来在所有可以使用有序数组的场合都可以使用有序链表来代替,有序链表对于有序数组的优越性在于插入操作不需要进行数据移动,并且可以实现动态内存分配。 有序链表也可以实现优先级队列。 有序链表的java实现...
  • 将两个有序链表合并为一个新的有序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例: 输入:1->2->4, 1->3->4 输出:1->1->2->3->4->4 /** * Definition for ...
  • 将两个有序链表合并为一个新的有序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例: 输入:1->2->4, 1->3->4 输出:1->1->2->3->4->4 /** * Definition ...
  • 有两个带头节点的有序链表,如何把他们合成一个有序链表?(假设链表带头节点) 我们通过取出其中一条链表的头节点作为合成后的有序链表的头节点(当然,这里也可以自己重新生成一个节点来作为头节点,但是使用原先的...
  • 将两个递增的有序链表合并为一个递增的有序链表。要求结果链表仍使用原来两个链表的存储空间, 不另外占用其它的存储空间。表中不允许有重复的数据。 void MergeList(LinkList &La,LinkList &Lb,LinkList ...
  • void MergeList...{//有序链表的合并 pa = La->next; //pa和pb分别是链表La和Lb的工作指针, pb = Lb->next; //分别初始化为相应链表的第一个结点 Lc = pc = La; //用La的头结点作为Lc的头结点 whil...
  • 两个有序链表的去重合并,
  • C++版本将两个有序链表合并为一个新的有序链表并返回原理及代码实现 /*! * Copyright (c) 2020,ZYF. * All Rights Reserved. * * \file MergerListNode.cpp * \brief C++版本将两个有序链表合并为一个新的有序链表并...
  • 两个初始有序链表如下 l1: 1----&amp;gt;2----&amp;gt;4 l2: 1----&amp;gt;3----&amp;gt;4 结果应该为: 1----&amp;gt;1----&amp;gt;2----&amp;gt;3----&amp;gt;4----&amp;gt;4...
  • //将两个有序链表并为一个有序链表算法,该程序也可以cFree环境运行。 // c1.h (程序名) #include<string.h> #include<ctype.h> #include<malloc.h> // malloc()等 #include<limits.h> //...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 166,435
精华内容 66,574
关键字:

有序链表