合并两个有序链表并且输出有序(面试题)
mergeSlist.h
//合并有序链表并且输出有序
#pragma once
#include<stdio.h>
#include<windows.h>
#include<assert.h>
#include<stdlib.h>
typedef int DataType;
typedef struct ListNode {
DataType val;
struct ListNode *next;
}ListNode;
// 初始化
void ListInit(ListNode **ppFirst)
{
assert(ppFirst != NULL);
*ppFirst = NULL;
}
// 销毁
void ListDestroy(ListNode **ppFirst)
{
assert(ppFirst != NULL);
ListNode *pNode, *pNext;
pNode = *ppFirst;
while (pNode != NULL) {
pNext = pNode->next;
free(pNode);
pNode = pNext;
}
*ppFirst = NULL;
}
//合并有序链表并且输出有序
//申请新空间
ListNode * CreateNewNode(int data)
{
ListNode *pNewNode = (ListNode *)malloc(sizeof(ListNode));
//assert(pNewNode);
pNewNode->val = data;
pNewNode->next = NULL;
return pNewNode;
}
//尾插
void PushBack(ListNode **ppFirst, int data)
{
assert(ppFirst != NULL);
ListNode *pNewNode = CreateNewNode(data);
if (*ppFirst == NULL) {
*ppFirst = pNewNode;
return;
}
ListNode *pNode;
pNode = *ppFirst;
while (pNode->next != NULL) {
pNode = pNode->next;
}
// pNode 就是倒数第一个
pNode->next = pNewNode;
}
ListNode* Merge(ListNode* pHead1, ListNode* pHead2)
{
ListNode *p1 = pHead1;
ListNode *p2 = pHead2;
ListNode *pNewFirst = NULL;
while (p1 != NULL && p2 != NULL) {
if (p1->val < p2->val) {
// 有改进空间,否则每次都需要遍历新链表
PushBack(&pNewFirst, p1->val);
p1 = p1->next;
}
else {
// 有改进空间,否则每次都需要遍历新链表
PushBack(&pNewFirst, p2->val);
p2 = p2->next;
}
}
// 有一个链表为空了
ListNode *pNotEmpty = p1;
if (p1 == NULL) {
pNotEmpty = p2;
}
// 把不空的链表剩余结点插入新链表
while (pNotEmpty) {
PushBack(&pNewFirst, pNotEmpty->val);
pNotEmpty = pNotEmpty->next;
}
return pNewFirst;
}
void Print(ListNode *pFirst)
{
ListNode *pNode;
for (pNode = pFirst; pNode; pNode = pNode->next) {
printf("%d -> ", pNode->val);
}
printf("NULL\n");
}
void Testmerge()
{
ListNode *pFirst1;
ListNode *pFirst2;
ListInit(&pFirst1);
PushBack(&pFirst1, 1);
PushBack(&pFirst1, 5);
PushBack(&pFirst1, 10);
Print(pFirst1);
ListInit(&pFirst2);
PushBack(&pFirst2, 4);
PushBack(&pFirst2, 6);
PushBack(&pFirst2, 8);
Print(pFirst2);
ListNode *pNewFirst=Merge(pFirst1, pFirst2);
Print(pNewFirst);
ListDestroy(&pFirst1);
ListDestroy(&pFirst2);
}
//在牛客网的oj环境下编译通过的
合并有序链表并且输出有序
申请新空间
//ListNode * CreateNewNode(int data)
//{
// ListNode *pNewNode = (ListNode *)malloc(sizeof(ListNode));
// //assert(pNewNode);
// pNewNode->val = data;
// pNewNode->next = NULL;
// return pNewNode;
//}
尾插
//void PushBack(ListNode **ppFirst, int data)
//{
// assert(ppFirst != NULL);
// ListNode *pNewNode = CreateNewNode(data);
// if (*ppFirst == NULL) {
// *ppFirst = pNewNode;
// return;
// }
// ListNode *pNode;
// pNode = *ppFirst;
// while (pNode->next != NULL) {
// pNode = pNode->next;
// }
// // pNode 就是倒数第一个
// pNode->next = pNewNode;
//}
//ListNode* Merge(ListNode* pHead1, ListNode* pHead2)
//{
// ListNode *p1 = pHead1;
// ListNode *p2 = pHead2;
// ListNode *pNewFirst = NULL;
//
// while (p1 != NULL && p2 != NULL) {
// if (p1->val < p2->val) {
// // 有改进空间,否则每次都需要遍历新链表
// PushBack(&pNewFirst, p1->val);
// p1 = p1->next;
// }
// else {
// // 有改进空间,否则每次都需要遍历新链表
// PushBack(&pNewFirst, p2->val);
// p2 = p2->next;
// }
// }
// // 有一个链表为空了
// ListNode *pNotEmpty = p1;
// if (p1 == NULL) {
// pNotEmpty = p2;
// }
// // 把不空的链表剩余结点插入新链表
// while (pNotEmpty) {
// PushBack(&pNewFirst, pNotEmpty->val);
// pNotEmpty = pNotEmpty->next;
// }
// return pNewFirst;
//}
main.c
//#include"sqlistsearchk.h"
//#include"complex.h"
#include"mergeSlist.h"
int main()
{
//TestSList();
//TestCN();
Testmerge();
system("pause");
return 0;
}
总结:对于链表方面的题,我们必须多动手画图分析,上面是合并有序链表,如有疑问,请您留言,谢谢访问!!!