/*函数mergelist完成的功能是:将两个已按从小到大次序排序的不带头结点的链表合并成一个新的不带头结点的单链表,要合并的两个链表的头指针分别为ahead和bhead。请填空,将函数补充完整。*/
#include <iostream>
using namespace std;
struct LNode {
int data;
LNode *next;
};
typedef LNode *LinkList;
LinkList mergelist(LinkList ahead, LinkList bhead)
{
LinkList chead, ap, bp, cp;
ap = ahead;
bp = bhead;
chead = NULL;
while ( // ahead!=NULL&&bhead!=NULL ) // 【 正确答案: ap&&bp 或 ap!=NULL&&bp!=NULL】)
{
if (ap->data <= bp->data)
{
if (chead == NULL)
chead = cp = ap;
else {
cp->next = ap;
cp = ap;
}
ap=ap->next //【 正确答案: ap=ap->next】;
}
else
{
if (chead == NULL)
chead = cp = bp;
else {
cp->next = bp;
cp = bp;
}
bp=bp->next //【 正确答案: bp=bp->next】;
}
}
// cp=NULL // 【 正确答案: cp->next=ap!=NULL?ap:bp 或 cp->next=bp!=NULL?bp:ap 或 cp->next=ap==NULL?bp:ap 或 cp->next=bp==NULL?ap:bp】;
return (chead);
}
/*【输入形式】第一行:单链表中元素个数m
第二行:单链表中的m个整数
第三行:k值
【输出形式】倒数第k个元素的值(不存在倒数第k个元素输出"no")
【样例输入】
【样例输出】
33
【样例说明】
输入:
5
13 24 50 33 56
6
输出:no*/
#include<iostream>
using namespace std;
struct Node
{
int date;
Node* next;
} ;
typedef Node* LinkList;
void createList(LinkList& L,int m) //一定要用引用。引用就是指针的指针,单用指针是不行的。
/*在函数调用时用指针或者引用做参数,表示把变量的地址传递给子函数,但是子函数只能修改指针所指变量的值,
并不能修改指针的指向。如果想要修改指针的指向,就要用指针的指针,或者指针的引用。
链表做参数时,其实就是头结点的指针,在遍历,查找这种操作做子函数时,链表不会发生改变,就用头结点的指针做参数就可以了。
但在增加,修改,删除这种操作时,链表会发生改变,这就表示头结点指针所指的这块内存会发生改变,也就是指针的指向可能会发生改变,这种情况下就要用头指针的引用。 */
{
L=new Node;//new一个头结点的地址给L;
L->next=NULL;
Node* r;//定义一个node 型指针,r是随链表每个节点移动的指针。
r=L;//r先指向头节点。
Node* p; //定义一个node 型指针
for(int i=1;i<=m;i++) //有等于号。
{
p=new Node; //为p申请后面每个结点的地址。
cin>>p->date;//写入p的date域里的值。
r->next=p; //头结点的next域指向p;
r=p;//指针r 移动到p的位置;
}
r->next=NULL;//最后一个结点的next域指向空。
}
void printList(Node* L)
{
Node* p;
p=L->next;
for(p=L->next;p!=NULL;p=p->next) //最后一个结点的next域为空,最后一个结点不为空。
cout<<p->date;
cout<<endl;
}
Node* getElem(Node* L,int k)
{
int num=0;
Node* p;
p=L->next;
if(p==NULL);
num=0;
while(p)
{
num++;
p=p->next;
}
int n;
n=num-k+1;
int count=0;
Node* p1;
p1=L->next;
while(p1)
{
count++;
if(count==n)
return p;
else
p1=p1->next;
}
}
int main()
{
int m;
cin>>m;
Node* L; //只要一个头,后面的next域先不管。
createList(L,m);
printList(L);
int k;
cin>>k;
Node* p=getElem(L,k);
if(p)
cout<<p->date;
else
cout<<"no"<<endl;
return 0;
}
——————————————————————————————
//自己练的
#include <iostream>
using namespace std;
struct Node {
int data;
Node *next;
};
typedef Node *LinkList;
void createList(LinkList &L,int n) { //因为要改变l,随意要用l的引用。
Node *p,*r;
L=new Node; //l是头指针 的地址
L->next=NULL;//头指针指向空。
r=L; //r指向头节点。
for(int i=1; i<=n; i++) {
p=new Node;//新建节点,第一个节点,o开头的节点是头节点。
cin>>p->data;//给第一个结点的数据域赋值。
r->next=p;//让头结点的指针域指向第一个节点。
r=p;//r移动到p的位置。
}
r->next=NULL;//让最后一个结点的指针域指向空;
}
void printList(LinkList L) {//不改变l,不需要引用。
Node *p;
p=L->next;//p指向头指针的next域,即第一个节点。
while(p) { //只要p指向的节点不为空,
cout<<p->data<<" ";
p=p->next;//p指向p的next域,移动到下一个节点。
}
cout<<endl;
}
Node* getElem(LinkList L,int k) //结构型函数。参数为头指针,和倒数第k的数。
{
int num=0;
LinkList p1; //p1是一个node型指针。
p1=L->next; //p指向头指针的next域,即第一个节点。
if(p1==NULL) //p1==null,一个节点都没有。
num=0;
while(p1){ //只要p1不等于空。
num++; //计数。
p1=p1->next; //p1指向p1的next域,移动到下一个节点。
} //num完成统计节点的个数。
int temp=0;
int n=num-k+1; //共10个,倒数第三个,即第8个。8=10-3+1;
LinkList p; //p1是一个node型指针。
p=L->next; //p指向头指针的next域,即第一个节点。
/*if(p==NULL)
cout<<"no";
if(k>m)
cout<<"no";*/
while(p) //只要p1不等于空。
{
temp++;
if(temp==n)
{
return p;
}
else
p=p->next; //p指向p的next域,移动到下一个节点。
}
}
int main() {
LinkList L; //单链表的头节点
int m,k;
cin>>m; //m是单链表的长度
createList(L,m); // 建一个长为m,头节点为l的单链表
cin>>k; //k为倒数第k个节点。
Node *p=getElem(L,k); //得到倒数第k个节点的地址后赋值给p.
if(p)
cout<<p->data; //p不为null,则输出p的date域里的值。
else
cout<<"no"; //没找到p,输出“no".
return 0;
}
/*【问题描述】已知某带头结点的单链表中存放着若干整数,请删除该单链表中元素在[x, y]之间的所有结点,要求算法的时间复杂度为O(n),空间复杂度为O(1)。
【输入形式】第一行:单链表中元素个数m
第二行:单链表中的m个整数
第三行:要删除的元素值所在区间[x,y]对应的x和y
【输出形式】
删除元素后的单链表中剩下的元素值
【样例输入】
5
13 24 50 33 56
30 50
【样例输出】
13 24 56
【样例说明】
【评分标准】*/
#include <iostream>
using namespace std;
struct Node {
int data;
Node *next;
};
typedef Node *LinkList;
void createList(LinkList &L,int n) {
Node *p,*r;
L=new Node;
L->next=NULL;
r=L;
for(int i=1; i<=n; i++) {
p=new Node;
cin>>p->data;
r->next=p;
r=p;
}
r->next=NULL;
}
void printList(LinkList L) {
Node *p;
p=L->next;
while(p) {
cout<<p->data<<" ";
p=p->next;
}
cout<<endl;
}
void delElem(LinkList L, int x, int y) {//创建链表用了引用,删除链表某个元素没用引用。
Node *p,*q;//指针p随链表移动,q指向要删除的节点,最后删除p.
p=L;//p指向头节点,不指向头结点的next。
while(p->next) {
if(p->next->data>=x&&p->next->data<=y) {
q=p->next;//这个要先 。
p->next=q->next;//这个要后。
delete q;//最后删除q.
} else {
p=p->next;
}
}
}
int main() {
LinkList L;
int m;
int x,y;
cin>>m;
createList(L,m);
cin>>x>>y;
delElem(L,x,y);
printList(L);
return 0;
}
/*【问题描述】已知某带头结点的单链表中存放着若干整数,请找出这批整数的最大值。
【输入形式】
第一行:整数个数m
第二行:m个整数
【输出形式】
m个整数中的最大值
【样例输入】
5
13 24 50 33 56
【样例输出】56*/
#include <iostream>
using namespace std;
struct Node{
int data;
Node *next;
};
typedef Node *LinkList;
void createList(LinkList &L,int n) {
Node *p,*r;
L=new Node;
L->next=NULL;
r=L;
for(int i=1; i<=n; i++) {
p=new Node;
cin>>p->data;
r->next=p;
r=p;
}
r->next=NULL;
}
int getMax(LinkList L)
{
LinkList p, pr;
p = L->next;
pr = p->next;
while (pr)
{
if (pr->data > p->data)
p = pr;
pr = pr->next;
}
return p->data;
}
int main(){
int m;
LinkList h;
cin>>m;
createList(h,m);
cout<<getMax(h);
return 0;
}
/*【问题描述】为从键盘终端输入的m个整数创建带头结点的有序单链表存储结构,使输入的数据元素在单链表中按照元素值递增有序。
【输入形式】
第一行:单链表中元素个数m
第二行:单链表中的m个整数
【输出形式】
按递增有序形式输出m个整数
【样例输入】
5
1 3 2 4 5
【样例输出】
1 2 3 4 5*/
#include <iostream>
using namespace std;
struct Node {
int data;
Node *next;
};
typedef Node *LinkList;
void createOList(LinkList &h,int n){
Node *p,*pre;
h=new Node;
h->next=NULL;
for(int i=1;i<=n;i++){
p=new Node; //p是新节点,边增边比。
cin>>p->data;
pre=h;
while(pre->next&&pre->next->data<p->data) //循环条件是(第一个)下一个节点存在并且 第一个结点的数据域的值小于新节点的数据域的值。
{
pre=pre->next; //pre移动到下一个节点。
}
p->next=pre->next; //p的next域存入pre下一个节点的地址。
pre->next=p; //pre的next域存入p的地址。
}
}
/*
第一次for循环;pre的next域为NULL,不执行while里面的循环。p的next域为空。pre的next域存入p的地址。即头节点后接入p.
for(int i=1;i<=n;i++){
p=new Node;
cin>>p->data;
pre=h; //每次循环pre都指向头节点,即从头开始一个一个对比选择插入。
p->next=pre->next; //p的next域为空。前后顺序要注意。
pre->next=p;
}
第二次for循环;
pre的next域不为空,假设第一个节点的数据域的值小于新节点的数据域的值,则执行while循环里的内容。pre指向第一个节点。新节点的next域存入第一个结点的next域的内容,第一个结点的next域存入新节点的地址。
*/
void printList(LinkList L) {
Node *p;
p=L->next;
while(p) {
cout<<p->data<<" ";
p=p->next;
}
cout<<endl;
}
int main() {
LinkList L;
int m;
cin>>m;
createOList(L,m);
printList(L);
return 0;
}