双向链表上的归并排序

2024年8月28日 | 阅读 18 分钟

归并排序是一种递归方法,它反复将列表分成两半。如果列表为空或只包含一个项(基本情况),则该列表按定义已排序。如果列表包含多个项,我们将其分成两半,并对两部分递归地执行归并排序。在两半排序后,将执行称为归并的基本过程。归并是将两个较小的已排序列表集成到一个已排序的新列表中。如果列表的长度小于或等于一,则该列表已经排序,不需要进一步处理。但是,如果长度大于一,则使用 Python 切片方法提取左半部分和右半部分。值得注意的是,列表可能甚至没有很多条目。这无关紧要,因为长度只会相差一。以下步骤概念性地展示了归并排序的工作原理:

  • 将未排序的列表分成 n 个子列表,每个子列表包含一个条目(包含一个元素的列表被认为是已排序的)。
  • 重复合并子列表以创建新的已排序子列表,直到只剩下一个子列表。这里将显示已排序的列表。

自上而下的实现

自上而下的归并排序技术采用索引递归地将列表(在本例中称为运行)拆分为子列表,直到子列表大小为 1,然后将这些子列表合并以生成已排序的列表。通过在每个递归级别旋转合并方向,可以避免复制回步骤(除了初始的一次性复制,也可以避免)。

考虑一个两元素数组以更好地理解这一点。组件在合并到 A[] 之前被传输到 B[]。如果有四个元素,来自 A[] 的单元素运行在递归级别的底部合并到 B[],而两元素运行在下一个更高递归级别合并到 A[]。随着每个递归级别,模式持续存在。

自然归并排序

自然归并排序类似于自下而上的归并排序,因为它利用输入中任何自然出现的运行(已排序序列)。列表(或等效地,磁带或文件)是用于**单调**和**位元**(交替上升/下降)运行的有用数据结构(用作 FIFO 队列或 LIFO 堆栈)。自下而上的归并排序的起点是每个运行的长度为一个项目。

由于存在长的自然运行,自然归并排序在许多实际情况下被用作 Timsort 的基本组件。实际上,随机输入数据将包含许多偶然排序的短运行。因为需要合并的运行更少,所以在大多数情况下,自然归并排序可能不需要那么多遍。在最佳情况下,输入已经排序(即,它是一个单一的运行)。因此,自然归并排序只需要遍历数据一次。

优化归并排序

由于现代计算机采用多个内存层次结构,引用局部性在程序优化中至关重要。已经开发了归并排序算法的缓存感知变体,其操作经过精心设计,以最大程度地减少机器内存缓存中页面的进出。例如,分块归并排序算法在子数组大小达到 S 时停止拆分子数组。S 是适合 CPU 缓存的数据项数量。为了避免内存交换,每个子数组都使用插入排序等就地排序算法进行排序,然后以传统的递归方式完成常规归并排序。

现在让我们编写一些代码,借助归并排序算法对双向链表数据结构执行排序操作。

Java 代码

首先,让我们编写 Java 代码以对双向链表数据结构执行归并排序。

输出

上述代码给出以下输出。

Select one of the operations::

1. To insert a new node in the Doubly Linked List.
2. To display the nodes of the Doubly Linked List.
3. To perform Merge sort on the Doubly Linked List.
1
Enter integer element to insert
23

Do you want to continue (Type y or n) 

y

Select one of the operations::

1. To insert a new node in the Doubly Linked List.
2. To display the nodes of the Doubly Linked List.
3. To perform Merge sort on the Doubly Linked List.
1
Enter integer element to insert
76

Do you want to continue (Type y or n) 

y

Select one of the operations::

1. To insert a new node in the Doubly Linked List.
2. To display the nodes of the Doubly Linked List.
3. To perform Merge sort on the Doubly Linked List.
1
Enter integer element to insert
55

Do you want to continue (Type y or n) 

y

Select one of the operations::

1. To insert a new node in the Doubly Linked List.
2. To display the nodes of the Doubly Linked List.
3. To perform Merge sort on the Doubly Linked List.
1
Enter integer element to insert
20
Do you want to continue (Type y or n) 

y

Select one of the operations::

1. To insert a new node in the Doubly Linked List.
2. To display the nodes of the Doubly Linked List.
3. To perform Merge sort on the Doubly Linked List.
1
Enter integer element to insert
89

Do you want to continue (Type y or n) 

y

Select one of the operations::

1. To insert a new node in the Doubly Linked List.
2. To display the nodes of the Doubly Linked List.
3. To perform Merge sort on the Doubly Linked List.
78  1
Enter integer element to insert
78

Do you want to continue (Type y or n) 

y

Select one of the operations::

1. To insert a new node in the Doubly Linked List.
2. To display the nodes of the Doubly Linked List.
3. To perform Merge sort on the Doubly Linked List.
32 1  1
Enter integer element to insert
31

Do you want to continue (Type y or n) 

y

Select one of the operations::

1. To insert a new node in the Doubly Linked List.
2. To display the nodes of the Doubly Linked List.
3. To perform Merge sort on the Doubly Linked List.
1
Enter integer element to insert
68

Do you want to continue (Type y or n) 

y

Select one of the operations::

1. To insert a new node in the Doubly Linked List.
2. To display the nodes of the Doubly Linked List.
3. To perform Merge sort on the Doubly Linked List.
2
Doubly Linked List::
Forward Traversal using next pointer
68 31 78 89 20 55 76 23 Backward Traversal using prev pointer
23 76 55 20 89 78 31 68 
Do you want to continue (Type y or n) 

y

Select one of the operations::

1. To insert a new node in the Doubly Linked List.
2. To display the nodes of the Doubly Linked List.
3. To perform Merge sort on the Doubly Linked List.
3
Quicksort done.

Do you want to continue (Type y or n) 

y

Select one of the operations::

1. To insert a new node in the Doubly Linked List.
2. To display the nodes of the Doubly Linked List.
3. To perform Merge sort on the Doubly Linked List.
2
Doubly Linked List::
Forward Traversal using next pointer
20 23 31 55 68 76 78 89 Backward Traversal using prev pointer
89 78 76 68 55 31 23 20 
Do you want to continue (Type y or n) 

n

C++ 代码

现在,让我们编写 C++ 代码以对双向链表数据结构执行归并排序。

输出

上面的 C++ 代码给出以下输出。

Select one of the operations::
1. To insert a new node in the Doubly Linked List.
2. To display the nodes of the Doubly Linked List.
3. To perform Merge sort on the Doubly Linked List.
1
Enter the value of the node to be inserted
12

Do you want to continue (Type y or n) 
y

Select one of the operations::
1. To insert a new node in the Doubly Linked List.
2. To display the nodes of the Doubly Linked List.
3. To perform Merge sort on the Doubly Linked List.
1
Enter the value of the node to be inserted
78

Do you want to continue (Type y or n) 
y

Select one of the operations::
1. To insert a new node in the Doubly Linked List.
2. To display the nodes of the Doubly Linked List.
3. To perform Merge sort on the Doubly Linked List.
1
Enter the value of the node to be inserted
45

Do you want to continue (Type y or n) 
y

Select one of the operations::
1. To insert a new node in the Doubly Linked List.
2. To display the nodes of the Doubly Linked List.
3. To perform Merge sort on the Doubly Linked List.
1
Enter the value of the node to be inserted
33

Do you want to continue (Type y or n) 
y

Select one of the operations::
1. To insert a new node in the Doubly Linked List.
2. To display the nodes of the Doubly Linked List.
3. To perform Merge sort on the Doubly Linked List.
1
Enter the value of the node to be inserted
92

Do you want to continue (Type y or n) 
y

Select one of the operations::
1. To insert a new node in the Doubly Linked List.
2. To display the nodes of the Doubly Linked List.
3. To perform Merge sort on the Doubly Linked List.
1
Enter the value of the node to be inserted
45

Do you want to continue (Type y or n) 
y

Select one of the operations::
1. To insert a new node in the Doubly Linked List.
2. To display the nodes of the Doubly Linked List.
3. To perform Merge sort on the Doubly Linked List.
1
Enter the value of the node to be inserted
65

Do you want to continue (Type y or n) 
y

Select one of the operations::
1. To insert a new node in the Doubly Linked List.
2. To display the nodes of the Doubly Linked List.
3. To perform Merge sort on the Doubly Linked List.
2
Contents of the Doubly Linked List are::
Forward Traversal using next pointer
65 45 92 33 45 78 12 
Backward Traversal using prev pointer
12 78 45 33 92 45 65 
Do you want to continue (Type y or n) 
y

Select one of the operations::
1. To insert a new node in the Doubly Linked List.
2. To display the nodes of the Doubly Linked List.
3. To perform Merge sort on the Doubly Linked List.
3
Merge sort applied successfully on the Doubly Linked List.

Do you want to continue (Type y or n) 
y

Select one of the operations::
1. To insert a new node in the Doubly Linked List.
2. To display the nodes of the Doubly Linked List.
3. To perform Merge sort on the Doubly Linked List.
2
Contents of the Doubly Linked List are::
Forward Traversal using next pointer
12 33 45 45 65 78 92 
Backward Traversal using prev pointer
92 78 65 45 45 33 12 
Do you want to continue (Type y or n) 
n

C 代码

现在,让我们编写 C 代码以对双向链表数据结构执行归并排序。

输出

上面的 C 代码给出以下输出。

Select one of the operations::
1. To insert a new node in the Doubly Linked List.
2. To display the nodes of the Doubly Linked List.
3. To perform Merge sort on the Doubly Linked List.
1

Enter the value of the node to be inserted
22

Do you want to continue (Type y or n)
y

Select one of the operations::
1. To insert a new node in the Doubly Linked List.
2. To display the nodes of the Doubly Linked List.
3. To perform Merge sort on the Doubly Linked List.
1

Enter the value of the node to be inserted
89

Do you want to continue (Type y or n)
y

Select one of the operations::
1. To insert a new node in the Doubly Linked List.
2. To display the nodes of the Doubly Linked List.
3. To perform Merge sort on the Doubly Linked List.
1

Enter the value of the node to be inserted
54

Do you want to continue (Type y or n)
y

Select one of the operations::
1. To insert a new node in the Doubly Linked List.
2. To display the nodes of the Doubly Linked List.
3. To perform Merge sort on the Doubly Linked List.
1

Enter the value of the node to be inserted
32

Do you want to continue (Type y or n)
y

Select one of the operations::
1. To insert a new node in the Doubly Linked List.
2. To display the nodes of the Doubly Linked List.
3. To perform Merge sort on the Doubly Linked List.
1

Enter the value of the node to be inserted
81

Do you want to continue (Type y or n)
y

Select one of the operations::
1. To insert a new node in the Doubly Linked List.
2. To display the nodes of the Doubly Linked List.
3. To perform Merge sort on the Doubly Linked List.
1

Enter the value of the node to be inserted
47

Do you want to continue (Type y or n)
y

Select one of the operations::
1. To insert a new node in the Doubly Linked List.
2. To display the nodes of the Doubly Linked List.
3. To perform Merge sort on the Doubly Linked List.
1

Enter the value of the node to be inserted
8 3

Do you want to continue (Type y or n)
y

Select one of the operations::
1. To insert a new node in the Doubly Linked List.
2. To display the nodes of the Doubly Linked List.
3. To perform Merge sort on the Doubly Linked List.
1

Enter the value of the node to be inserted
97

Do you want to continue (Type y or n)
y

Select one of the operations::
1. To insert a new node in the Doubly Linked List.
2. To display the nodes of the Doubly Linked List.
3. To perform Merge sort on the Doubly Linked List.
2

Contents of the Doubly Linked List are::

Forward Traversal using next pointer
97 3 47 81 32 54 89 22 
Backward Traversal using prev pointer
22 89 54 32 81 47 3 97 
Do you want to continue (Type y or n)
y

Select one of the operations::
1. To insert a new node in the Doubly Linked List.
2. To display the nodes of the Doubly Linked List.
3. To perform Merge sort on the Doubly Linked List.
3

Merge sort applied successfully on the Doubly Linked List.

Do you want to continue (Type y or n)
y

Select one of the operations::
1. To insert a new node in the Doubly Linked List.
2. To display the nodes of the Doubly Linked List.
3. To perform Merge sort on the Doubly Linked List.
2
Contents of the Doubly Linked List are::

Forward Traversal using next pointer
3 22 32 47 54 81 89 97 
Backward Traversal using prev pointer
97 89 81 54 47 32 22 3 
Do you want to continue (Type y or n)
n 

通过这种方式,我们编写了 Java、C++ 和 C 代码来对双向链表数据结构执行归并排序操作。为双向链表数据结构编写了三个函数,一个是向双向链表添加新节点,第二个是显示双向链表的所有节点并显示与这些节点关联的值,第三个也是最后一个函数是执行归并排序操作在双向链表数据结构上。

用户首先在双向链表数据结构中添加足够数量的节点。成功添加节点后,通过从每次操作后显示的菜单中选择第三个选项,在双向链表数据结构上执行归并排序操作,该选项将调用代码中编写的 **mergesort()** 函数,并将双向链表的根节点作为参数传递。

成功完成归并排序操作后,用户可以通过选择用户的第二个选项来显示双向链表中节点的值,从而确认快速排序操作的结果。所有操作完成后,用户可以通过输入“n”或“N”字符退出代码。