SDKD 软件18 链表(1)#函数题,编程题#
6-1 带头结点的单链表就地逆置 (10 分)
思路
首先有两种特殊情况,空链表无法逆置,只有一个元素无需逆置
其他情况可统一为以下代码中的方法
将数据元素倒序连接,不断向前移动头结点
代码
void ListReverse_L(LinkList &L)
{
/*
cur:当前
nex:下一个
*/
LNode *nex, *cur = L->next;
if(cur && cur->next) //判断是否有第一个节点以及第二个节点
{
nex = L->next->next;//将头节点的后第二个节点取下
L->next->next = NULL;
while(nex)
{
cur = L->next;
L->next = nex;
nex = nex->next;
L->next->next = cur;
}
}
}
7-1 两个有序链表序列的合并 (20 分)
思路
不断从两个链表的头部取取节点,哪个链表的头结点的data小就将其链接到结果链表的末端
代码
//库函数头文件包含
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
//函数状态码定义
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
typedef int Status;
typedef int ElemType; //假设线性表中的元素均为整型
typedef struct LNode
{
ElemType data;
struct LNode *next;
} LNode, *LinkList;
Status ListCreate_L(LinkList &L)
{
LNode *rearPtr, *curPtr; //一个尾指针,一个指向新节点的指针
L = (LNode *)malloc(sizeof(LNode));
if (!L)
exit(OVERFLOW);
L->next = NULL; //先建立一个带头结点的单链表
rearPtr = L; //初始时头结点为尾节点,rearPtr指向尾巴节点
while (1) //每次循环都开辟一个新节点,并把新节点拼到尾节点后
{
curPtr = (LNode *)malloc(sizeof(LNode)); //生成新结点
if (!curPtr)
exit(OVERFLOW);
scanf("%d", &curPtr->data); //输入元素值
if (curPtr->data == -1)
break;
curPtr->next = NULL; //最后一个节点的next赋空
rearPtr->next = curPtr;
rearPtr = curPtr;
}
return OK;
}
void ListPrint_L(LinkList &L)
{
if (L->next)
{
//输出单链表
LNode *p = L->next; //p指向第一个元素结点
while (p != NULL)
{
if (p->next != NULL)
printf("%d ", p->data);
else
printf("%d", p->data);
p = p->next;
}
}
else
{
printf("NULL");
}
}
void ListMerge_L(LinkList a, LinkList b, LinkList c)
{
a = a->next;
b = b->next;
while (a && b)
{
if (a->data <= b->data)
{
c->next = a;
a = a->next;
}
else
{
c->next = b;
b = b->next;
}
c = c->next;
}
c->next = a ? a : b;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
#endif
LinkList L1, L2, L;
if ((ListCreate_L(L1) && ListCreate_L(L2)) != OK)
{
printf("表创建失败!!!\n");
return -1;
}
L = (LNode *)malloc(sizeof(LNode));
if (!L)
{
printf("表创建失败!!!\n");
return -1;
}
ListMerge_L(L1, L2, L);
ListPrint_L(L);
return 0;
}
STL代码
#include <bits/stdc++.h>
using namespace std;
vector<int> vec;
int main()
{
for (int i = 0; i < 2; ++i)
{
int a;
while (1)
{
cin >> a;
if (a == -1)
break;
vec.push_back(a);
}
}
sort(vec.begin(), vec.end());
if (vec.begin() == vec.end())
printf("NULL");
else
for (vector<int>::iterator it = vec.begin(); it != vec.end(); it++)
{
if (it != vec.begin())
cout << " ";
cout << *it;
}
}
7-2 两个有序链表序列的交集 (20 分)
思路
由于该题目所提供的链表是非降序的,那么我们就很容易求出链表的的并集
我们采取这样一种方法:
从两个链表的前端开始比较元素的大小,谁的元素更小就丢弃该节点,直到某个链表中没有元素了结束操作.
中途发生两节点相同的情况就copy此节点放在答案链表的尾部.
代码
//库函数头文件包含
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
//函数状态码定义
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
typedef int Status;
typedef int ElemType; //假设线性表中的元素均为整型
typedef struct LNode
{
ElemType data;
struct LNode *next;
} LNode, *LinkList;
Status ListCreate_L(LinkList &L)
{
LNode *rearPtr, *curPtr; //一个尾指针,一个指向新节点的指针
L = (LNode *)malloc(sizeof(LNode));
if (!L)
exit(OVERFLOW);
L->next = NULL; //先建立一个带头结点的单链表
rearPtr = L; //初始时头结点为尾节点,rearPtr指向尾巴节点
while (1) //每次循环都开辟一个新节点,并把新节点拼到尾节点后
{
curPtr = (LNode *)malloc(sizeof(LNode)); //生成新结点
if (!curPtr)
exit(OVERFLOW);
scanf("%d", &curPtr->data); //输入元素值
if (curPtr->data == -1)
break;
curPtr->next = NULL; //最后一个节点的next赋空
rearPtr->next = curPtr;
rearPtr = curPtr;
}
return OK;
}
void ListPrint_L(LinkList &L)
{
if (L->next)
{
//输出单链表
LNode *p = L->next; //p指向第一个元素结点
while (p != NULL)
{
if (p->next != NULL)
printf("%d ", p->data);
else
printf("%d", p->data);
p = p->next;
}
}
else
printf("NULL");
}
Status ListMerge_L(LinkList a, LinkList b, LinkList c)
{
a = a->next;
b = b->next;
while (a && b)
{
if (a->data <= b->data)
{
c->next = a;
a = a->next;
}
else
{
c->next = b;
b = b->next;
}
c = c->next;
}
c->next = a ? a : b;
return OK;
}
Status ListIntersection_L(LinkList a, LinkList b, LinkList cur)
{
LinkList tmp;
a = a->next;
b = b->next;
while (a && b)
{
if (a->data < b->data)
a = a->next;
else if (a->data > b->data)
b = b->next;
else
{
tmp = (LNode *)malloc(sizeof(LNode));
if (!tmp)
exit(OVERFLOW);
tmp->data = a->data;
tmp->next = NULL;
cur->next = tmp;
cur = tmp;
a = a->next;
b = b->next;
}
}
//cur->next = NULL;
return OK;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
#endif
LinkList L1, L2, L;
if ((ListCreate_L(L1) && ListCreate_L(L2)) != OK)
{
printf("表创建失败!!!\n");
return -1;
}
L = (LNode *)malloc(sizeof(LNode));
if (!L)
{
printf("表创建失败!!!\n");
return -1;
}
ListIntersection_L(L1, L2, L);
ListPrint_L(L);
return 0;
}
STL代码
#include <bits/stdc++.h>
using namespace std;
vector<int> v, vec[2];
int main()
{
for (int i = 0; i < 2; ++i)
{
int a;
while (1)
{
cin >> a;
if (a == -1)
break;
vec[i].push_back(a);
}
}
set_intersection(vec[0].begin(), vec[0].end(), vec[1].begin(), vec[1].end(), inserter(v, v.begin()));
if (v.begin() == v.end())
printf("NULL");
else
for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
{
if (it != v.begin())
cout << " ";
cout << *it;
}
}