单链表最大值
根据已知数组建立链表
求单链表已知最大结点
本题要求求出单链表值最大的结点并返回。要求实现两个函数。
函数接口定义:
/* 建立单链表并返回单链表的头指针 */
struct Node* buildLinkedList(int* arr, int n);
/* 求单链表值最大的结点,返回指向最大值结点的指针。
* 若单链表为空,则返回NULL。
*/
struct Node* getMax(struct Node* head);
其中arr存放创建单链表所需的数据(均为正整数),n 的值不超过1000; head 为不带附加头结点的单链表的头指针。
裁判测试程序样例:
#include <stdio.h>
#include <stdlib.h>
struct Node {
int data;
struct Node* next;
};
/* 建立单链表并返回单链表的头指针 */
struct Node* buildLinkedList(int* arr, int n);
/* 求单链表值最大的结点 */
struct Node* getMax(struct Node* head);
int main(int argc, char const *argv[])
{
int *a, n, i;
scanf("%d", &n);
a = (int*)malloc(n * sizeof(int));
for (i = 0; i < n; ++i) {
scanf("%d", &a[i]);
}
struct Node* head = NULL;
head = buildLinkedList(a, n);
struct Node* pMax = getMax(head);
if (pMax)
printf("%d\n", pMax->data);
else
printf("-1\n");
free(a);
return 0;
}
/* 请在这里填写答案 */
输入样例:
4
3 7 9 5
输出样例:
9
struct Node* buildLinkedList(int* arr, int n)//提供已知数组建立链表
{
struct Node *p,*p1,*head=NULL;
for(int i=0;i<n;i++)
{
p=(struct Node *)malloc(sizeof(struct Node));
p->data=arr[i];
p->next=NULL;
if(head==NULL) head=p;
else p1->next=p;
p1=p;
}
return head;
}
struct Node* getMax(struct Node* head)//求单链表已知最大结点
{
struct Node *p1,*max;
p1=head->next;
max=head;
while(p1)
{
if(p1->data>max->data) max=p1;
p1=p1->next;
}
return max;
}
查找学生链表
根据键盘输入数据创建链表
在链表中查询
本题要求将键盘输入的学生信息创建成单向链表,并在学生信息链表中查找学生信息。
学生信息链表结点定义如下:
typedef struct List{
int sno;
char sname[10];
List *next;
};
需要创建的函数包括:
创建学生信息链表函数:CreateList
查找学生信息链表函数:Find
函数接口定义:
List * CreateList(); //键盘输入若干学生学号和姓名,学号与姓名以空格符间隔,当输入的学号为-1时,输入结束,创建学生信息链表函数,返回学生链表的头指针。
List * Find(List *head, int no) //在学生信息链表(头指针为head)中查询学号为no的学生,返回该学生结点的指针。
裁判测试程序样例:
int main(void){
List *list=NULL,*p;
int no;
list=CreateList();
while(~scanf("%d", &no))
{
p=Find(list,no);
if( p ) printf("%s\n", p->sname);
else printf("Not Found!\n");
}
return 0;
}
/* 请在这里填写答案 */
输入样例1:
20180002 王红
20180006 张勇
20180008 吴涛
20170010 林玉
-1 xx
20180002
输出样例1:
在这里给出相应的输出。例如:
王红
输入样例2:
20180002 王红
20180006 张勇
20180008 吴涛
20170010 林玉
-1 xx
20170015
输出样例2:
Not Found!
List * CreateList() //键盘输入若干学生学号和姓名,学号与姓名以空格符间隔,当输入的学号为-1时,输入结束,创建学生信息链表函数,返回学生链表的头指针。
{
List *p,*p1,*head=NULL;
int x;
char name[10];
while(1)
{
scanf("%d",&x);
if(x==-1)//注意该地方对“XX”的处理,p->sname=name会编译错误
{
scanf("%s",name);
break;
}
p=(List *)malloc(sizeof(List));
p->sno=x;
scanf("%s",p->sname);
p->next=NULL;
if(head==NULL) head=p;
else p1->next=p;
p1=p;
}
return head;//不可忘!!!
}
List * Find(List *head, int no) //在学生信息链表(头指针为head)中查询学号为no的学生,返回该学生结点的指针。
{
List *p1=head;
while(p1)
{
if(p1->sno==no) break;
p1=p1->next;
}
return p1;
}
工作备忘录的生成(链表)
添加至链表,排序
如果某项工作与若干项工作冲突(在做该项工作时,需要同时做其它工作),则在该工作名前加’*'。
每天都要处理很多事务,为了更好地安排工作,希望在每天开始工作前,根据工作记录,生成工作备忘录。首先输入工作记录数(大于0的一个整数),再逐条输入各条工作记录,每条工作记录包括:工作名,开始时间,结束时间。假设每项工作的开始时间均小于它的结束时间,并且各项工作的开始时间互不相同。
我们的工作是需要把这些工作记录按开始时间排序并输出,在输出时,如果某项工作与若干项工作冲突(在做该项工作时,需要同时做其它工作),则在该工作名前加’*'。
函数接口定义:
Node* add(Node *, Node *);
void display(Node *);
裁判测试程序样例:
#include<iostream>
#include <string>
using namespace std;
struct Node{
string name;
int start;
int end;
Node *next;
};
Node* add(Node *, Node *);
void display(Node *);
bool check(Node *head)
{
if(head==NULL || head->next==NULL) return true;
Node *p=head->next;
if(head->start > p->start) return false;
return check(p);
}
int main()
{
Node *head=NULL, *p;
int i, repeat;
cin>>repeat;
for(i=0;i<repeat;i++){
p = new Node;
cin>>p->name>>p->start>>p->end;
p->next=NULL;
head = add(head, p);
}
if(!check(head)) cout<<"ERROR"<<endl;
display(head);
return 0;
}
/* 请在这里填写答案 */
输入样例:
4
aaa 19 20
ccc 169 200
ddd 153 170
bbb 20 111
输出样例:
aaa 19 20
bbb 20 111
*ddd 153 170
*ccc 169 200
Node *add(Node *head, Node *p)//添加至链表,排序
{
Node *p1,*p2;
p1=head;
p2=p1;
while(p1)
{
if(p->start<p1->start) break;//题目的排序要求:按开始时间排序
p2=p1;
p1=p1->next;
}
if(p1==head) //从头结点插入的情况要单独讨论
{
head=p;
p->next=p1;
}
else{
p->next=p1;
p2->next=p;
}
return head;
}
void display(Node *head)//如果某项工作与若干项工作冲突(在做该项工作时,需要同时做其它工作),则在该工作名前加'*'。
{
Node *p1,*p2;
p1=head;
int k;//标志是否与其他工作冲突
while(p1)
{
k=0;
p2=head;
while(!k&&p2!=p1)//在链表中,若p2排在p1前面,则可能p2->end>p1->start
{
if(p2->end>p1->start)
{
k=1;
break;
}
p2=p2->next;
}
p2=p1->next;
while(!k&&p2)//在链表中,若p2排在p1后面,则可能p1->end>p2->start
{
if(p1->end>p2->start)
{
k=1;
break;
}
p2=p2->next;
}
if(k==1) cout<<"*";
cout<<p1->name<<' '<<p1->start<<' '<<p1->end<<endl;
p1=p1->next;
}
}
单链表(流浪狗收养所)
插入,排序
清除排序在前的数据
怡山小学生物组的同学在课外要收养一批流浪狗。在流浪狗进入收养基地时,课外指导老师会给每一只狗取一个唯一的编号,并且判定它的年龄,让组长输入流浪狗档案。档案以单链表存储,按年龄为序(从小到大),如果年龄相同,则后录入的记录应该放在前面。
由于组里新来了一位二年级的淘气组员小林,喜欢将已经输入的档案再次输入。他在输入时,会输入正确的编号,却可能输入错误的年龄(但他所输入的年龄不会大于真实的年龄),因此在输入档案外,组长还需要对档案进行清理,清除那些重复档案。
输入时:首先输入任务类型:1代表插入新的记录, 2代表清理档案, 0代表退出。如果需要加入新的记录,则接下来将依次输入编号和年龄。
输出时:按照从前到后的顺序输出档案中的所有的记录,每条记录单独占一行。
函数接口定义:
Dog *insert(string &no, int age); //加入一只狗的信息
Dog *clear(); //清理档案
裁判测试程序样例:
#include <iostream>
#include <string>
using namespace std;
struct Dog{
string no;
int age;
Dog *next;
};
Dog *head=NULL;
void *del(Dog *p){
if(p!=NULL) {
del(p->next);
delete p;
}
}
void display(Dog *p){
if(p!=NULL){
cout<<p->no<<' '<<p->age<<endl;
display(p->next);
}
}
Dog *clear();
Dog *insert(string &no, int age);
int main()
{
int task, age;
string no;
cin>>task;
while(task>0){
switch(task){
case 1:cin>>no>>age; head=insert(no, age); display(head); break;
case 2:head=clear(); display(head); break;
}
cin>>task;
}
del(head);
return 0;
}
/* 请在这里填写答案 */
输入样例:
1 abcd 2
1 cd 5
1 cd 4
1 zz 4
2
0
输出样例:
abcd 2
abcd 2
cd 5
abcd 2
cd 4
cd 5
abcd 2
zz 4
cd 4
cd 5
abcd 2
zz 4
cd 5
Dog *insert(string &no, int age)//加入一只狗的信息,排序
{
Dog *p,*p1,*p2;
p1=head;
p2=p1;
p=new Dog;
p->no=no;
p->age=age;
p->next=NULL;
while(p1)
{
if(p->age<=p1->age) break;
p2=p1;
p1=p1->next;
}
if(p1==head)//插入讨论头结点
{
head=p;
p->next=p1;
}
else{
p->next=p1;
p2->next=p;
}
return head;
}
Dog *clear() //清理档案,清除排序在前的数据
{
Dog *p1,*p2,*p3;
p1=head;
p3=p1;
while(p1)
{
p2=p1->next;
while(p2)
{
if(p1->no==p2->no) break;
p2=p2->next;
}
if(p2)//不要用if(p1->no==p2->no),当p2为空时会产生段错误
{
if(p1==head)
{
head=p1->next;
p1=head;
p3=p1;
}
else
{
p3->next=p1->next;
p1=p3->next;
}
}
else
{
p3=p1;//不要出现在循环开始的时候
p1=p1->next;
}
}
return head;
}
判断链表结点对称
循环双链表不可以用p1!=NULL
设计算法,判断带头结点的循环双向链表中的数据结点是否对称。
如果对称,输出“yes”
如果不对称,输出“no”
链表空则输出“NULL”
链表结构及操作函数接口定义:
typedef char ElemType;
typedef struct DNode //定义循环双链表结点类型
{
ElemType data;
struct DNode *prior,*next;
} DLinkNode;
void InitList(DLinkNode *&L); //初始化一个空的带头节点的双向循环链表 裁判程序实现,略去不表
void DestroyList(DLinkNode *&L); // 销毁链表 裁判程序实现,略去不表
bool ListInsert(DLinkNode *&L,int i,ElemType e); // 在链表第i个节点处插入元素为e的节点 。裁判程序实现,略去不表。
void DispList(DLinkNode *L); // 正向顺序输出链表,输出时每个节点元素之间以空格符间隔,以换行符结束。
int Symm(DLinkNode *L); // 判断链表是否对称,对称时返回1,不对称时返回0,链表为空时返回-1。
裁判测试程序样例:
#include <stdio.h>
void InitList(DLinkNode *&L); //裁判程序实现,略去不表
void DestroyList(DLinkNode *&L); //裁判程序实现,略去不表
bool ListInsert(DLinkNode *&L,int i,ElemType e);//裁判程序实现,略去不表
//要求写出以下函数实现
void DispList(DLinkNode *L);
int Symm(DLinkNode *L);
int main()
{
DLinkNode *h;
ElemType e;
InitList(h);
int i=1;
char ch;
while((ch=getchar())!='\n')
{
ListInsert(h,i,ch);
i++;
}
DispList(h);
if(Symm(h)==1)
printf("yes\n");
else if (Symm(h)==0)printf("no\n");
else printf("NULL\n");
DestroyList(h);
return 0;
}
/* 请在这里填写答案 */
输入样例:
在这里给出一组输入。例如:
abcxba
输出样例:
在这里给出相应的输出。例如:
a b c x b a
no
void DispList(DLinkNode *L)// 正向顺序输出链表,输出时每个节点元素之间以空格符间隔,以换行符结束。
{
DLinkNode *p1;
p1=L->next;
while(p1!=L)//因为是循环双向链表,所以不可以用p1!=NULL
{
printf("%c",p1->data);
printf(" ");
p1=p1->next;
}
printf("\n");
}
int Symm(DLinkNode *L)// 判断链表是否对称,对称时返回1,不对称时返回0,链表为空时返回-1。
{
DLinkNode *p1,*p2;
if(L->next==L) return -1;
p1=L->next;
p2=L->prior;
while(p1!=p2)
{
if(p1->data!=p2->data) return 0;
p1=p1->next;
p2=p2->prior;
}
return 1;
}
集合的基本运算(单链表)
带头结点链表
数组元素值尾插法创建链表
销毁链表
单链表元素递增排序,交换已知链表中数据的顺序
求两有序集合ha、hb的并集hc,建立hc
求两有序集合ha、hb的的交集hc
求两有序集合ha、hb的差集hc,差集概念,x对x的差集
有两个字符集合A和B,现在要求实现集合的并、交、差运算。
要求:集合用单链表表示,假设同一个集合中不存在重复的元素。A、B集合元素最多不超过100个,至少有一个元素。
算法实现:
1)将两个集合的元素按递增方式排序,构成有序单链表。
2)采用二路归并算法求集合的并集、交集和差集。
链表结构及操作函数接口定义:
typedef char ElemType;
typedef struct LNode //定义单链表结点类型
{
ElemType data;
struct LNode *next;
} LinkList;
void DispList(LinkList *L); //输出链表元素,每个结点元素值以空格符间隔,以换行符结束。
void CreateListR(LinkList *&L,ElemType a[],int n); //用数组元素值尾插法创建链表。
void DestroyList(LinkList *&L);//销毁链表。
void sort(LinkList *&L) //单链表元素递增排序。
void Union(LinkList *ha,LinkList *hb,LinkList *&hc) //求两有序集合ha、hb的并集hc。
void InterSect(LinkList *ha,LinkList *hb,LinkList *&hc) //求两有序集合ha、hb的的交集hc。
void Subs(LinkList *ha,LinkList *hb,LinkList *&hc) //求两有序集合ha、hb的差集hc。
裁判测试程序样例:
#include <stdio.h>
#include <malloc.h>
int main()
{
LinkList *ha,*hb,*hc;
ElemType a[100]={0};
ElemType b[100]={0};
int i=0;
char ch;
while((ch=getchar())!='\n')
{
a[i++]=ch;
}
CreateListR(ha,a,i);
i=0;
while((ch=getchar())!='\n')
{
b[i++]=ch;
}
CreateListR(hb,b,i);
printf("A: ");DispList(ha);
printf("B: ");DispList(hb);
sort(ha);
sort(hb);
printf("sorted A: ");DispList(ha);
printf("sorted B: ");DispList(hb);
Union(ha,hb,hc);
printf("Union C: ");DispList(hc);
InterSect(ha,hb,hc);
printf("InterSect C: ");DispList(hc);
Subs(ha,hb,hc);
printf("Subs C: ");DispList(hc);
DestroyList(ha);
DestroyList(hb);
DestroyList(hc);
return 0;
}
/* 请在这里填写答案 */
输入样例:
在这里给出一组输入。例如:
adecfgvjkz
akidqe
输出样例:
在这里给出相应的输出。例如:
A: a d e c f g v j k z
B: a k i d q e
sorted A: a c d e f g j k v z
sorted B: a d e i k q
Union C: a c d e f g i j k q v z
InterSect C: a d e k
Subs C: c f g j v z
void DispList(LinkList *L) //输出链表元素,每个结点元素值以空格符间隔,以换行符结束。
{
LinkList *p1;
p1=L->next;
while(p1)
{
printf("%c",p1->data);
printf(" ");
p1=p1->next;
}
printf("\n");
}
void CreateListR(LinkList *&L,ElemType a[],int n) //用数组元素值尾插法创建链表。
{
LinkList *p,*p1;
L=(LinkList *)malloc(sizeof(LinkList));
L->next=NULL;
p1=L;
for(int i=0;i<n;i++)
{
p=(LinkList *)malloc(sizeof(LinkList));
p->data=a[i];
p->next=NULL;
p1->next=p;
p1=p;
}
}
void DestroyList(LinkList *&L)//销毁链表。
{
LinkList *p1,*p2;
p1=L;
while(p1)
{
p2=p1;
p1=p1->next;
free(p2);
}
}
void sort(LinkList *&L) //单链表元素递增排序,交换已知链表中数据的顺序
{
LinkList *p,*p1,*p2;
p1=L->next;
while(p1)
{
p2=p1->next;
while(p2)
{
if(p2->data<p1->data)
{
char t;
t=p1->data;
p1->data=p2->data;
p2->data=t;
}
p2=p2->next;
}
p1=p1->next;
}
}
void Union(LinkList *ha,LinkList *hb,LinkList *&hc) //求两有序集合ha、hb的并集hc,建立hc
{
LinkList *p1,*p2,*p3,*p;
p1=ha->next;
p2=hb->next;
hc=(LinkList *)malloc(sizeof(LinkList));
p3=hc;
while(p1&&p2)
{
if(p1->data<p2->data)
{
p=(LinkList *)malloc(sizeof(LinkList));
p->data=p1->data;
p->next=NULL;
p3->next=p;
p3=p;
p1=p1->next;
}
else if(p1->data>p2->data)
{
p=(LinkList *)malloc(sizeof(LinkList));
p->data=p2->data;
p->next=NULL;
p3->next=p;
p3=p;
p2=p2->next;
}
else{
p=(LinkList *)malloc(sizeof(LinkList));
p->data=p1->data;
p->next=NULL;
p3->next=p;
p3=p;
p1=p1->next;
p2=p2->next;
}
}
while(p1)
{
p=(LinkList *)malloc(sizeof(LinkList));
p->data=p1->data;
p->next=NULL;
p3->next=p;
p3=p;
p1=p1->next;
}
while(p2)
{
p=(LinkList *)malloc(sizeof(LinkList));
p->data=p2->data;
p->next=NULL;
p3->next=p;
p3=p;
p2=p2->next;
}
}
void InterSect(LinkList *ha,LinkList *hb,LinkList *&hc) //求两有序集合ha、hb的的交集hc。
{
LinkList *p1,*p2,*p3,*p;
p1=ha->next;
p2=hb->next;
hc=(LinkList *)malloc(sizeof(LinkList));
p3=hc;
while(p1)
{
while(p2)
{
if(p1->data==p2->data) break;
p2=p2->next;
}
if(p2)
{
p=(LinkList *)malloc(sizeof(LinkList));
p->data=p1->data;
p->next=NULL;
p3->next=p;
p3=p;
}
p2=hb->next;
p1=p1->next;
}
}
void Subs(LinkList *ha,LinkList *hb,LinkList *&hc) //求两有序集合ha、hb的差集hc,差集概念,x对x的差集
{
LinkList *p1,*p2,*p3,*p;
p1=ha->next;
p2=hb->next;
hc=(LinkList *)malloc(sizeof(LinkList));
p3=hc;
while(p1)
{
while(p2)
{
if(p1->data==p2->data) break;
p2=p2->next;
}
if(!p2)
{
p=(LinkList *)malloc(sizeof(LinkList));
p->data=p1->data;
p->next=NULL;
p3->next=p;
p3=p;
}
p2=hb->next;
p1=p1->next;
}
}
链表拼接
合并两个有序链表,不带头结点,重复数据不删
本题要求实现一个合并两个有序链表的简单函数。链表结点定义如下:
struct ListNode {
int data;
struct ListNode *next;
};
函数接口定义:
struct ListNode *mergelists(struct ListNode *list1, struct ListNode *list2);
其中list1和list2是用户传入的两个按data升序链接的链表的头指针;函数mergelists将两个链表合并成一个按data升序链接的链表,并返回结果链表的头指针。
裁判测试程序样例:
#include <stdio.h>
#include <stdlib.h>
struct ListNode {
int data;
struct ListNode *next;
};
struct ListNode *createlist(); /*裁判实现,细节不表*/
struct ListNode *mergelists(struct ListNode *list1, struct ListNode *list2);
void printlist( struct ListNode *head )
{
struct ListNode *p = head;
while (p) {
printf("%d ", p->data);
p = p->next;
}
printf("\n");
}
int main()
{
struct ListNode *list1, *list2;
list1 = createlist();
list2 = createlist();
list1 = mergelists(list1, list2);
printlist(list1);
return 0;
}
/* 你的代码将被嵌在这里 */
输入样例:
1 3 5 7 -1
2 4 6 -1
输出样例:
1 2 3 4 5 6 7
struct ListNode *mergelists(struct ListNode *list1, struct ListNode *list2)//合并两个有序链表,不带头结点,重复数据不删
{
struct ListNode *head=NULL,*p1,*p2,*p,*p4;
p1=list1;
p2=list2;
while(p1&&p2)
{
if(p1->data<p2->data)
{
p=(struct ListNode *)malloc(sizeof(struct ListNode));
p->data=p1->data;
p->next=NULL;
if(head==NULL) head=p;
else p4->next=p;
p4=p;
p1=p1->next;
}
else
{
p=(struct ListNode *)malloc(sizeof(struct ListNode));
p->data=p2->data;
p->next=NULL;
if(head==NULL) head=p;
else p4->next=p;
p4=p;
p2=p2->next;
}
}
while(p1)
{
p=(struct ListNode *)malloc(sizeof(struct ListNode));
p->data=p1->data;
p->next=NULL;
if(head==NULL) head=p;
else p4->next=p;
p4=p;
p1=p1->next;
}
while(p2)
{
p=(struct ListNode *)malloc(sizeof(struct ListNode));
p->data=p2->data;
p->next=NULL;
if(head==NULL) head=p;
else p4->next=p;
p4=p;
p2=p2->next;
}
return head;
}
奇数值结点链表
删除并新建链表
本题要求实现两个函数,分别将读入的数据存储为单链表、将链表中奇数值的结点重新组成一个新的链表。链表结点定义如下:
struct ListNode {
int data;
ListNode *next;
};
函数接口定义:
struct ListNode *readlist();
struct ListNode *getodd( struct ListNode **L );
函数readlist从标准输入读入一系列正整数,按照读入顺序建立单链表。当读到−1时表示输入结束,函数应返回指向单链表头结点的指针。
函数getodd将单链表L中奇数值的结点分离出来,重新组成一个新的链表。返回指向新链表头结点的指针,同时将L中存储的地址改为删除了奇数值结点后的链表的头结点地址(所以要传入L的指针)。
裁判测试程序样例:
#include <stdio.h>
#include <stdlib.h>
struct ListNode {
int data;
struct ListNode *next;
};
struct ListNode *readlist();
struct ListNode *getodd( struct ListNode **L );
void printlist( struct ListNode *L )
{
struct ListNode *p = L;
while (p) {
printf("%d ", p->data);
p = p->next;
}
printf("\n");
}
int main()
{
struct ListNode *L, *Odd;
L = readlist();
Odd = getodd(&L);
printlist(Odd);
printlist(L);
return 0;
}
/* 你的代码将被嵌在这里 */
输入样例:
1 2 2 3 4 5 6 7 -1
输出样例:
1 3 5 7
2 2 4 6
struct ListNode *readlist()
{
struct ListNode *head=NULL,*p1,*p;
int n;
while(1)
{
scanf("%d",&n);
if(n==-1) break;
p=(struct ListNode *)malloc(sizeof(struct ListNode));
p->data=n;
p->next=NULL;
if(head==NULL) head=p;
else p1->next=p;
p1=p;
}
return head;
}
struct ListNode *getodd( struct ListNode **L )//删除后新建链表
{
struct ListNode *head=NULL,*p1,*p2,*p,*p3;
p1=*L;
p2=p1;
while(p1)
{
if(p1->data%2!=0)
{
p=(struct ListNode *)malloc(sizeof(struct ListNode));
p->data=p1->data;
p->next=NULL;
if(head==NULL) head=p;//新建链表
else p3->next=p;
p3=p;
if(p1==*L)//删除,讨论头结点
{
*L=p1->next;
p1=*L;
p2=p1;
}
else{
p2->next=p1->next;
p1=p2->next;
}
}
else{
p2=p1;
p1=p1->next;
}
}
return head;
}
创建单链表
头插法和尾插法
本题要求实现单链表的头插法和尾插法建表。
要求写出CreateListF函数、 CreateListR函数和DispList函数。
说明:单链表带头结点。
链表结构及操作函数接口定义:
typedef char ElemType;
typedef struct LNode //定义单链表结点类型
{
ElemType data;
struct LNode *next; //指向后继结点
} LinkList;
LinkList * CreateListF(LinkList *L,ElemType a[],int n);//用数组元素值头插法建立单链表,返回单链表头结点指针。
LinkList * CreateListR(LinkList *L,ElemType a[],int n);//用数组元素值尾插法建立单链表,返回单链表头结点指针。
void DispList(LinkList *L); //输出单链表所有结点,如果链表为空,则输出NULL
void SetListNULL(LinkList *L); //裁判程序实现,删除链表所有数据结点,将链表置为空表。
裁判测试程序样例:
#include <stdio.h>
#include <malloc.h>
typedef char ElemType;
typedef struct LNode //定义单链表结点类型
{
ElemType data;
struct LNode *next; //指向后继结点
} LinkList;
LinkList * CreateListF(LinkList *L,ElemType a[],int n);//头插法建立单链表。
LinkList * CreateListR(LinkList *L,ElemType a[],int n);//尾插法建立单链表。
void DispList(LinkList *L); //输出单链表所有结点值,每个结点之间用空格间隔,如果链表为空,则输出NULL。全部输出用换行符结束。
void SetListNULL(LinkList *L);//删除链表所有数据结点,将链表置为空表。 裁判程序实现。
int main()
{
LinkList *L, *ha,*hb;
ElemType a[100]={0};
int i=0;
char ch;
while((ch=getchar())!='\n')
{
a[i++]=ch;
}
ha=CreateListR(L,a,i);
hb=CreateListF(L,a,i);
printf("A: ");DispList(ha);
printf("B: ");DispList(hb);
SetListNULL(ha);
SetListNULL(hb);
printf("A: ");DispList(ha);
printf("B: ");DispList(hb);
return 0;
}
void SetListNULL(LinkList *L);// 裁判程序实现,细节不表。删除链表所有数据结点,将链表置为空表。
{
...
}
/* 请在这里填写答案 */
输入样例:
在这里给出一组输入。例如:
abcdef
输出样例:
在这里给出相应的输出。例如:
A: a b c d e f
B: f e d c b a
A: NULL
B: NULL
LinkList * CreateListF(LinkList *L,ElemType a[],int n)//用数组元素值头插法建立单链表,返回单链表头结点指针。
{
L=(LinkList *)malloc(sizeof(LinkList));
L->next=NULL;
LinkList *p;
for(int i=0;i<n;i++)
{
p=(LinkList *)malloc(sizeof(LinkList));
p->data=a[i];
p->next=L->next;
L->next=p;
}
return L;
}
LinkList * CreateListR(LinkList *L,ElemType a[],int n)//用数组元素值尾插法建立单链表,返回单链表头结点指针。
{
L=(LinkList *)malloc(sizeof(LinkList));
L->next=NULL;
LinkList *p1,*p;
p1=L;
for(int i=0;i<n;i++)
{
p=(LinkList *)malloc(sizeof(LinkList));
p->data=a[i];
p->next=NULL;
p1->next=p;
p1=p;
}
return L;
}
void DispList(LinkList *L) //输出单链表所有结点,如果链表为空,则输出NULL
{
LinkList *p1;
if(L->next==NULL) printf("NULL");
p1=L->next;
while(p1)
{
printf("%c ",p1->data);
p1=p1->next;
}
printf("\n");
}
单链表逆置
间接头插
已知单链表的结点结构定义如下:
typedef struct _NODE_
{
int data;
struct _NODE_ *next;
} NODE;
说明:data 为数据域。next 为指针域,指示后继结点。
请编写函数,将带附加头结点的单链表逆置。
函数原型
void Reverse(NODE *head);
说明:参数 head 为单链表的头指针。函数将单链表中数据元素的排列顺序颠倒过来。
裁判程序
int main()
{
NODE *h;
Create(&h);
Input(h);
Reverse(h);
Output(h);
putchar('\n');
Destroy(&h);
return 0;
}
说明:Create 函数用于创建链表,Destroy 函数用于销毁链表。Input 函数用于输入链表:首先输入结点数,然后输入这些数据元素。Output 函数用于输出单链表,数据元素之间以空格间隔。
输入样例
5
28 47 79 52 36
输出样例
36 52 79 47 28
void Reverse(NODE *head)
{
NODE *p1,*p2;
p1=head->next;
head->next=NULL;
while(p1)
{
p2=p1;
p1=p1->next;
p2->next=head->next;
head->next=p2;
}
}