• 链表题目


    7-8 单向链表3 (10 分)

    编程实现:输入一个正整数 repeat (0<repeat<10),做 repeat 次下列运算:

    输入一个正整数 n(0<n<=9)和一组(n个)升序的整数,建立单向链表,再输入一个整数 x,把 x 插入到这组数据中,使该组数据仍然有序。

    输入输出示例:括号内为说明

    输入样例:

    4               (repeat=4) 
    5               (数据的个数n=5)
    1 2 4 5 7       (5个有序整数)
    3               (待插入整数x=3)
    4               (数据的个数n=4)
    1 2 5 7	        (4个有序整数)
    -10             (待插入整数x=-10)
    3               (数据的个数n=3)
    1 2 4	        (3个有序整数)
    100             (待插入整数x=100)
    5               (数据的个数n=5)
    1 2 4 5 7       (5个有序整数)
    4               (待插入整数x=4)
    

    输出样例:

    size=6:1 2 3 4 5 7 
    size=5:-10 1 2 5 7 
    size=4:1 2 4 100 
    size=6:1 2 4 4 5 7
    
    #include<iostream>
    using namespace std;
    struct Node{
    	int data;
    	struct Node *next;
    };
    struct Node *Create(int n)
    {
    	Node *p=NULL,*q=NULL,*head=NULL;
    	for(int i=0;i<n;i++)
    	{
    		q=new Node;//新建一个Node给q
    		q->next=NULL;//先让它的next为NULL,比较安全
    		cin>>q->data;
    		if(head==NULL)
    		{
    			head=p=q;//让三个指针都先指向第一个Node 
    		}
    		else
    		{
    			p->next=q;//q起到的作用就是把链表串起来
    			p=q;//将p移到链表的下一个位置上,以便下一次的串联 
    		}
    	}
    	return head;//返回头节点 
    }
    struct Node *Insert(Node *head,int x)//插入数x 
    {
    	Node *p,*q;
    	int flag=0;
    	p=head;
    	if(head==NULL) return head;
    	q=new Node;
    	q->data=x;
    	q->next=NULL;
    	if(p->data>x)//如果x的值小于链表中的第一个数 
    	{
    		q->next=p;
    		head=q;//如果替换了第一个数,记得要修改头节点
    		return head; 
    	} 
    	while(p->next!=NULL)
    	{
    		if(p->data<=x&&p->next->data>x)
    		{
    			q->next=p->next;
    			p->next=q;
    			flag=1;
    			break;
    		}
    		p=p->next;//指向下一个,往下一项移动 
    	}
    	if(flag==0)
    		p->next=q;
    	return head;
    }
    int main()
    {
    	int repeat;
    	cin>>repeat;
    	Node *head,*p;
    	for(int i=0;i<repeat;i++)
    	{
    		int n;
    		cin>>n;
    		int b;
    		head=Create(n);	
    		cin>>b;
    		head=Insert(head,b);
    		p=head;
    		cout<<"size="<<n+1<<":";
    		cout<<p->data;
    		p=p->next;
    		while(p!=NULL)
    		{
    			cout<<" "<<p->data;
    			p=p->next;
    		}
            cout<<endl;
    }
    	return 0;
    }
    
    

    7-12 单链表基本操作 (5 分)

    请编写程序实现单链表插入、删除结点等基本算法。给定一个单链表和一系列插入、删除结点的操作序列,输出实施上述操作后的链表。单链表数据域值为整数。

    输入格式:

    输入第1行为1个正整数n,表示当前单链表长度;第2行为n个空格间隔的整数,为该链表n个元素的数据域值。第3行为1个正整数m,表示对该链表施加的操作数量;接下来m行,每行表示一个操作,为2个或3个整数,格式为0 k d或1 k。0 k d表示在链表第k个结点后插入一个数据域值为d的结点,若k=0则表示表头插入。1 k表示删除链表中第k个结点,此时k不能为0。注:操作序列中若含有不合法的操作(如在长度为5的链表中删除第8个结点、删除第0个结点等),则忽略该操作。n和m不超过100000。

    输出格式:

    输出为一行整数,表示实施上述m个操作后的链表,每个整数后一个空格。输入数据保证结果链表不空。

    输入样例:

    5
    1 2 3 4 5
    5
    0 2 8
    0 9 6
    0 0 7
    1 0 
    1 6
    

    输出样例:

    7 1 2 8 3 5 
    
    #include<iostream>
    using namespace std;
    struct Node{
    	int data;
    	struct Node *next;
    };
    struct Node *Create(int n)//创建链表
    {
    	Node *p=NULL,*q=NULL,*head=NULL;
    	for(int i=0;i<n;i++)
    	{
    		q=new Node;//新建一个Node给q
    		q->next=NULL;//先让它的next为NULL,比较安全
    		cin>>q->data;
    		if(head==NULL)
    		{
    			head=p=q;//让三个指针都先指向第一个Node 
    		}
    		else
    		{
    			p->next=q;//q起到的作用就是把链表串起来
    			p=q;//将p移到链表的下一个位置上,以便下一次的串联 
    		}
    	}
    	return head;//返回头节点 
    }
    
    struct Node *Insert(Node *head,int k,int b)//在链表第k个节点后插入一个数值为d的节点 
    {
    	Node *p,*q;
    	p=head;
    	if(head==NULL) return head;
    	q=new Node;
    	q->data=b;
    	q->next=NULL;
    	if(k==0)
    	{
    		q->next=p;
    		head=q;
    		return head;
    	}
    	if(k!=0)
    	{
    		for(int i=1;i<k;i++)
    			p=p->next;
    		q->next=p->next;
    		p->next=q;
    		return head;
    	}
    }
    
    struct Node *Delete(Node *head,int k)//删除某个节点 
    {
    	Node *p;
    	p=head;
    	if(head==NULL) return head;
    	if(k==1)
    	{
    		p=p->next;
    		head=p;
    		return head;
    	}
    	else
    	{
    		while(k-2)
    		{
    			p=p->next;
    			k--;
    		}
    		p->next=p->next->next;
    		return head;
    	}
    }
    int main()
    {
    	int n;
    	Node *p,*head;
    	cin>>n;//为单链表的长度
    	head=Create(n);
    	int m;//为对链表的操作数量
    	cin>>m;
    	int count=n; 
    	for(int i=0;i<m;i++)
    	{
    		int a;
    		cin>>a;
    		if(a==0)
    		{
    			int k,b;
    			cin>>k>>b;
    			if(k>count)
    				continue;
    			count++;
    			head=Insert(head,k,b);
    			p=head;
    		}
    		else if(a==1)
    		{
    			int k;
    			cin>>k;
    			if(k>count||k==0)
    				continue;
    			count--;
    			head=Delete(head,k);
    			p=head;
    		}
    	}
    	p=head;
    	while(p!=NULL)
    		{
    			cout<<p->data<<" ";
    			p=p->next;
    		} 
    } 
    
    

    7-13 链表操作-插入、查找和删除 (100 分)

    请编写创建链表和输出链表的函数。对于以下数据结点的结构定义,
    针对带头结点的链表,请编程完成以下功能。
    struct LNode{
    int data;                  //数据域
    struct LNode *next;        //指针域
    };
    struct LNode *head;            //头指针
    输入数据包含若干组命令和数据,一组数据中的第1个字符代表命令,
    接下来的是该命令需要的数据。
    (1)如果命令是I,功能为创建空链表,对应函数:void List_Init(head);
    (2)如果命令是A,后跟一个整数data,功能为向链表尾部追加一个数据data,
    对应函数:void List_Append(head,data);
    (3)如果命令是C,后跟一个整数N,再跟N个整数,功能为向链表尾部追加N个
    数据,可通过调用List_Append()函数实现;
    (4)如果命令是P,功能遍历输出链表中所有数据,数据间用一个空格分隔,对应
    函数:void List_print(head),如果链表未建立,输出“List not defined!”,
    如果链表为空输出:“List is empty!”。
    

    以上为上一题目的内容,在此基础上,增加设计如下功能:

    (5)如果命令是N,后跟一个整数n和d,功能为向链表的第n个位置插入数据d,
    可通过调用List_Insert(head,n,d)函数实现;
    (6)如果命令是F,后跟一个整数d,功能为在链表查找数据d,返回其位序,若
    找不到返回-1。可通过调用List_Find(head,d)函数实现;
    (7)如果命令是D,后跟一个整数n,功能为删除链表第n个位置的数据,可通过
    调用List_Delete(head,n)函数实现。
    

    输入格式:

    若干组命令和数据,很多命令和数据写在一起请注意识别。

    输出格式:

    根据输入命令输出相应内容,详见输出样例。

    输入样例:

    I C 5 100 200 300 400 500 P
    F 500 N 3 23 N 5 31 P
    D 4 P F 99
    A 6 P
    

    输出样例:

    100 200 300 400 500
    index:5
    100 200 23 300 31 400 500
    100 200 23 31 400 500
    Not Found!
    100 200 23 31 400 500 6
    

    输入样例:

    I A 100 A 200 A 300 C 4 400 500 600 700 P
    F 800 F 500
    N 4 4 N 5 5 P
    D 2 D 2 D 2 P
    D 2 D 2 D 2 P
    D 1 D 1 P
    D 1 D 1 P
    

    输出样例:

    100 200 300 400 500 600 700
    Not Found!
    index:5
    100 200 300 4 5 400 500 600 700
    100 5 400 500 600 700
    100 600 700
    700
    List is empty!
    
    #include<iostream>
    using namespace std;
    struct Node{
    	int data;
    	struct Node *next;
    };
    struct Node *head;//在外部声明,则后面函数中可以直接用void不用struct 
    void List_Init(Node *&head)//新建一个空链表 
    {
    	head=new Node;
    	head->next=NULL;
    }
    void List_Append(Node *head,int data)//向链表的尾部追加一个数据data 
    {
    	Node *p,*q;
    	p=head;
    	q=new Node;
    	q->data=data;
    	q->next=NULL;
    	while(p->next!=NULL){
    		p=p->next;
    	}
    	p->next=q;
    }
    void List_print(Node *head)//遍历输出链表中的所有数据,如果链表未建立,输出"List not defined!"如果链表为空输出:"List is empty!" 
    {
    	Node *p;
    	if(head==NULL){
    		cout<<"List not defined!"<<endl;
    		return;
    	}
    	if(head->next==NULL){
    		cout<<"List is empty!"<<endl;
    		return;
    	}
    	p=head->next;//因为这是一个带头结点的链表,所以head实际上是没有数的,它指向的才存了第一个数 
    	cout<<p->data;
    	p=p->next;
    	while(p!=NULL){
    		cout<<' '<<p->data;
    		p=p->next;
    	}
    	cout<<endl;
    }
    void List_Insert(Node *head,int n,int d)//向链表的第n个位置插入数据d 
    {
    	int i;
    	Node *p,*q;
    	q=new Node;
    	q->data=d;
    	q->next=NULL;
    	p=head;
    	for(i=1;i<n;i++)p=p->next;
    	q->next=p->next;
    	p->next=q;
    }
    int List_Find(Node *head,int d)//在链表中查找数据d,并返回其位序,如果找不到则返回-1 
    {
    	int cnt=1;
    	Node *p;
    	p=head->next;
    	while(p!=NULL){
    		if(p->data==d)return cnt;
    		p=p->next;
    		cnt++;
    	}
    	return -1;
    }
    void List_Delete(Node *head,int n)//删除链表第n个位置的数据 
    {
    	Node *p,*q;
    	int i;
    	p=head;
    	q=p->next;
    	for(i=1;i<n;i++){
    		if(p!=NULL)p=p->next;
    	}
    	if(p==NULL || p->next==NULL)return;
    	q=p->next;
    	p->next=p->next->next;
    	delete q;
    }
    
    int main()
    {
    	head=NULL;
    	char c;
    	int i,n,N,data;
    	while(cin>>c){
    		if(c=='I')List_Init(head);
    		if(c=='A'){
    			cin>>data;
    			List_Append(head,data);
    		}
    		if(c=='C'){
    			cin>>N;
    			for(i=0;i<N;i++){
    				cin>>data;
    				List_Append(head,data);
    			}
    		}
    		if(c=='P')List_print(head);
    		if(c=='N'){
    			cin>>n>>data;
    			List_Insert(head,n,data);
    		}
    		if(c=='F'){
    			cin>>data;
    			if(List_Find(head,data)==-1)cout<<"Not Found!"<<endl;
    			else cout<<"index:"<<List_Find(head,data)<<endl;
    		}
    		if(c=='D'){
    			cin>>n;
    			List_Delete(head,n);
    		}
    	}
    	return 0;
    }
    
    • 若已建立下面的链表结构,指针 pq 分别指向图中所示结点,则不能将 q 所指结点插入到链表末尾的语句是(C )。

    1.jpg

    A.

    q->next = NULL;
    p = p->next; 
    p->next = q;
    

    B.

    p = p->next; 
    q->next = p->next;
    p->next = q;
    

    C.

    p = p->next; 
    q->next = p;
    p->next = q;
    

    D.

    p = (*p).next; 
    (*q).next = (*p).next;
    (*p).next = q;
    

    需要分配较大空间,插入和删除不需要移动元素的线性表,其存储结构是(B)。

    A.单链表

    B.静态链表

    C.线性链表

    D.顺序存储结构

    • 顺序存储和链式存储没有优劣之分,根据算法要求灵活使用,但链式存储结构比顺序存储结构能更方便地表示各种逻辑结构

    • 对于一个线性表既要求能够进行较快速地插入和删除,又要求存储结构能反映数据之间的逻辑关系,则应该用(链式存储方式 )。

    • ‘静态链表需要分配较大的连续空间,插入和删除不需要移动元素

    • 若用单链表来表示队列,则应该选用带尾指针的循环链表

    • 删除最后一个链表元素时,就算设置尾指针,也无法删除最后一个节点,也只能从头结点往后遍历,删除最后一个节点,时间复杂度为O(n)

    • 设对n(n>1)个元素的线性表的运算只有4种:删除第一个元素;删除最后一个元素;在第一个元素之前插入新元素;

    • 在最后一个元素之后插入新元素,则最好使用(只有头结点指针没有尾结点指针的循环双链表)。

    • 需要分配较大空间,插入和删除不需要移动元素的线性表,其存储结构为( 静态链表)。

    单链表中,增加一个头结点的目的是(C )

    A.使单链表至少有一个结点。

    B.标识表结点中首结点的位置。

    C.方便运算的实现。

    D.说明单链表是线性表的链式存储

    解析:(1) 对带头结点的链表,在表的任何结点之前插入结点或删除表中任何结点,所要做的都是修改前一结点的指针域,因为任何元素结点都有前驱结点。若链表没有头结点,则首元素结点没有前驱结点,在其前插入结点或删除该结点时操作会复杂些。 (2) 对带头结点的链表,表头指针是指向头结点的非空指针,因此空表与非空表的处理是一样的。

    2-1

    线性表若采用链式存储结构时,要求内存中可用存储单元的地址 B

    A 必须是连续的
    B 连续或不连续都可以
    C 部分地址必须是连续的
    D 一定是不连续的

    2-2

    线性表L在什么情况下适用于使用链式结构实现? A

    A 需不断对L进行删除插入
    B 需经常修改L中的结点值
    C L中含有大量的结点
    D L中结点结构复杂

    2-3

    链表不具有的特点是: B

    A 插入、删除不需要移动元素
    B 方便随机访问任一元素
    C 不必事先估计存储空间
    D 所需空间与线性长度成正比

    2-7

    可以用带表头附加结点的链表表示线性表,也可以用不带头结点的链表表示线性表,前者最主要的好处是(B)。 (1分)

    A 可以加快对表的遍历
    B 使空表和非空表的处理统一
    C 节省存储空间
    D 可以提高存取表元素的速度

    2-8

    在单链表中,要删除某一指定结点,必须先找到该结点的(A)。 (1分)

    A 直接前驱
    B 自身位置
    C 直接后继
    D 直接后继的后继

    2-9

    以下关于链式存储结构的叙述中,(C)是不正确的。 (1分)

    A 结点除自身信息外还包括指针域,因此存储密度小于顺序存储结构
    B 逻辑上相邻的结点物理上不必邻接
    C 可以通过计算直接确定第i个结点的存储地址
    D 插入、删除运算操作方便,不必移动结点

    以下结构类型可用来构造链表的是(B)。

    A.struct aa{ int a;int * b;};

    B.struct bb{ int a;bb * b;};

    C.struct cc{ int * a;cc b;};

    D.struct dd{ int * a;aa b;};

    链表要有一个next,next的类型要与结构体的类型一致

    2-13

    关于delete运算符的下列描述中,(C)是错误的。

    A.它必须用于new返回的指针;

    B.使用它删除对象时要调用析构函数;

    C.对一个指针可以使用多次该运算符;

    D.指针名前只有一对方括号符号,不管所删除数组的维数。

    2-14

    以下程序中,new语句干了什么。(C)

    int** num;

    num = new int* [20];

    A.分配了长度为20的整数数组空间,并将首元素的指针返回。

    B.分配了一个整数变量的空间,并将其初始化为20。

    C.分配了长度为20的整数指针数组空间,并将num[0]的指针返回。

    D.存在错误,编译不能通过。

    关于new运算符的下列描述中,(D)是错误的。

    A.它可以用来动态创建对象和对象数组;

    B.使用它创建的对象或对象数组可以使用运算符delete删除;

    C.使用它创建对象时要调用构造函数;

    D.使用它创建对象数组时必须指定初始值

    2-11

    表达式 “new int”的返回值类型是?

    A.int

    B.int *

    C.int &

    D.无法确定

    设void f1(int * m,long & n);int a;long b;则以下调用合法的是(B)。

    A.f1(a,b);

    B.f1(&a,b);

    C.f1(a,&b);

    D.f1(&a,&b);

  • 相关阅读:
    2333
    STL string
    后缀自动机的应用
    省选一轮
    等价类计数问题(Polya定理和burnside引理)
    Prufer序列与树的计数(坑)
    分治算法
    生成函数
    莫队算法
    Xamarin 技术解析
  • 原文地址:https://www.cnblogs.com/fzujly/p/14851275.html
Copyright © 2020-2023  润新知