小题精练

【例1】有一个递增非空单链表,设计一个算法删除值域重复的结点。例如,{1,1,2,3,3,3,4,4,7,7,7,9,9,9} 经过删除后变成 {1,2,3,4,7,9}

/* 思路:p,q指针一前一后,紧密相连。若两指针所指的data相同,则删除q所指的结点,然后一前一后继续遍历 */

void delete(LNode *L){
    
    

	LNode *p,*q,*s;
	p=L->next;
	q=p->next;

	while(q!=NULL){
    
    
		if(p->data==q->data){
    
    
			s=q;
			p->next=q->next;
			q=q->next;
			free(s);
		}
		else{
    
    
			p=q;
			q=q->next;
		}
	}
	
}

【例2】设计一个算法删除单链表 L (有头结点)中的一个最小值结点。

/* 思路:假设单链表中第一个值为最小值,并用指针 r 指向,并用 s 指针指向它的前驱结点
		再定义两个指针 p,q ,一前一后紧密相连,用来遍历单链表
		遍历的同时比较 q 所指向的值与 r 所指向的值的大小,若更小,则更新 r 指针以及 s指针 */

void deleteMin(LNode *L){
    
    

	LNode *s,*r,*p,*q;
	s=L;
	r=L->next;
	p=L->next;
	q=p->next;
	

	while(q!=NULL){
    
    
		if(q->data < r->data){
    
    
			r=q;
			s=p;
		}
		p=q;
		q=q->next;
	}
    r->next=s->next;
    free(s);
    
}


【例3】有一个线性表,采用带头结点的单链表L来存储。设计一个算法将其逆置。要求不能建立新结点,只能通过表中已有结点的重新组合来完成。

/* 思路:这里可以将L中的元素作为逆转后L的元素来源,即将L->next 设置为空,
然后将头结点后的一串结点用头插法逐个插入L中,这样新的L中的元素顺序正好是逆序的。 */

void reverse(LNode *L){
    
    

	LNode *p,*q;         
	p=L->next;
	L->next=NULL;

	while(p!=NULL){
    
    
		q=p->next;
		p->next=L->next;
		L->next=p;
		p=q;
	}

}

【例4】设计一个算法,将一个头结点为A的单链表(其数据域为整数〉分解成两个单链表A和B,使得A链表只含有原来链表中 data域为奇数的结点,而B链表只含有原链表中 data域为偶数的结点,且保持原来的相对顺序。

/* 思路:对A而言是删除data为偶数的结点,对B而言是采用尾插法增加那些被A删除的结点。 */

void split2(LNode *A,LNode *&B){
    
    

	B=(LNode*)malloc(sizeof(LNode));
	B->next=NULL;
	
	LNode *p,*q,*r,*s;
	p=A;
	q=A->next;
	r=B;

	while(q!=NULL){
    
    
		if(q->data%2==0){
    
          //偶数时,A删 B增
			s=q;               //提前把即将被删除的结点保留,便于后续在B中添加
			p->next=q->next;   //将偶数从A中删除
			q=p->next;
			s->next=NULL;      //这一句必须写,将其变成一个没有后续的结点
			r->next=s;         
			r=s;
		}
		else{
    
                        //奇数时,A继续遍历		
			p=q;
			q=q->next;
		};	      		
	}
		
}	

猜你喜欢

转载自blog.csdn.net/qq_48795733/article/details/126524634