双向循环链表大于0前移而小于0 后移

双向循环链表>0前移,<0 后移

题目

已知带头几点的双向循环链表头结点为list,除头结点外每个结点的数据域为整型,请写一算法,将链表中所有数据域大于0的结点放在小于0的前面。若链表中除头结点以外其他的为空,这返回0,否则,返回1.

代码

第一种

需要移动指针,即直接将>0的数据移动到list的后继结点,
缺点:频繁修改指针。

// > 0 前移 ,<0 后移
int PRINT(DLinklist list){    
	DLinklist p,q;    
	p=list->rlink;    
	if (p==list)    {        
		return 0;   
	 }    
	 while (p!=list)    {        
	 	if(p->data<0){            
	 		p=p->rlink;        
	 	}else        {            
	 		q=p;            
	 		p->llink->rlink=p->rlink;   
	 		p->rlink->llink=p->llink;            
	 		p=p->rlink;
	 		// 将结点插入到list后面
            		q->rlink=list->rlink;            
            		q->llink=list;            
            		list->rlink->llink=q;           
            		 list->rlink=q;       
            	 }           
            }   
             printf("\n");     
             p=list->rlink;    
             while (p!=list)    {        
             	printf("%d,",p->data);        
             	p=p->rlink;  
              }    
              return 1;
      }

第二种

直接交换数据域,不用移动指针,同时从链表的两边向中间靠近,思路有点像“快速排序”的思想。

// 双向循环链表>0前移,<0 后移
int PRINTVAL(DLinklist list){     
	DLinklist p=list->rlink,q=list->llink;     
	int temp;    
	if (p==list)    {        
		return 0;    
	}    
	while (p!=q)    {       
		while (p->data>0&&p!=list)       {           
			p=p->rlink;       
		}       
		while (q->data<0&&q!=list)       {           
			q=q->llink;      
		 }             
		  if (q->rlink!=p)       {          
		  	temp = p->data;          
		  	p->data=q->data;          
		  	q->data=temp;          
		  	p=p->rlink;          
		  	q=q->llink;          
		  	if (q->rlink==p||(p==list&&q==list))          {             
		  		return 1;          // 链表已满足条件,立马结束循环
		  	}                 
		  }else       {          
		  	 return 1;       
		  }  // if  
	}// while
    }

明显第二种相对第一种来说,时间复杂度要快好多。

猜你喜欢

转载自blog.csdn.net/honeylife/article/details/99443087