1. 程式人生 > >資料結構C語言第二版(53頁作業)

資料結構C語言第二版(53頁作業)

#include<iostream>
using namespace std;
typedef struct //定義順序表 
{
	int *elem;
	int length;
}SqList;
typedef struct LNode  //定義單向連結串列 
{
	int date;
	struct LNode *next;
}LNode,*Linklist;
typedef struct DuLNode  //定義雙向連結串列 
{
	int date;
	struct DuLNode *prior;
	struct DuLNode *next;
}DuLNode,*DuLinklist;
void creatlist_d(Linklist &L,int n)//尾插法單鏈表 
{
	L=new LNode;   //建立頭結點 
	L->next=NULL;  //頭結點後繼置空 
	LNode *p;       
	Linklist r;    
	r=L;
	for(int i=0;i<n;i++)
	{
		p=new LNode;
        cin>>p->date;   //輸入資料 
		p->next=NULL;  //後繼置空 
		r->next=p;     //插入 
		r=p;           //指標後移 
	}
}
void creatlist_du(DuLinklist &LA,int n) //尾插法雙向連結串列
{
	LA=new DuLNode;
	LA->next =NULL;
	DuLinklist r;
	DuLNode *p;
	r=LA;
	for(int i=0;i<n;i++)
	{
		p=new DuLNode;
		cin>>p->date ;
		p->next =NULL;
		p->prior =r;
		r->next=p;
		r=p;
	}
} 
void traverse(Linklist L)//遍歷單鏈表
{
	if(L->next ==NULL)
	{
		cout<<" 該連結串列已無資料 "<<endl;
		return ; 
	}
	cout<<"結果為:";
     LNode *p=L->next;
	
	while(p)
	{
		cout<<p->date<<" ";
		p=p->next;
	}
	cout<<endl;
}
void traverse_d(DuLinklist L)//遍歷雙向連結串列
{
	if(L->next ==NULL)
	{
		cout<<" 該連結串列已無資料 "<<endl;
		return ; 
	}
	cout<<"結果為:";
     DuLNode *p=L->next;
	
	while(p)
	{
		cout<<p->date<<" ";
		p=p->next;
	}
	cout<<endl;
}
//第一題:合併兩個遞增的有序連結串列 時間複雜度O(length(LA)+length(LB))
void   mergelist_1(Linklist &LA,Linklist &LB,Linklist &LC)
{
	Linklist pa=LA->next;
	Linklist pb=LB->next;
    LC=LA;
	Linklist pc=LA;
	while(pa&&pb)
	{
		if(pa->date < pb->date)
		{
			pc->next=pa;
			pc=pa;
			pa=pa->next;
		}
		else if(pa->date == pb->date)
		{
			pc->next=pa;
			pc=pa;
			pa=pa->next;
			pb=pb->next;
	    }
	    else
	    {
	    	pc->next=pb;
	    	pc=pb;
	    	pb=pb->next;
		}
	}	
	    pc->next=pa?pa:pb;
		delete LB; 
      traverse(LC);	 
 } 
 //第二題:將兩個非遞減的有序連結串列合併過程一個非遞增的有序連結串列  時間複雜度O(length(LA)+length(LB) 頭插法)
 void mergelist_2(Linklist &LA,Linklist &LB,Linklist &LC)
 {
 	Linklist pa=LA->next;
 	Linklist pb=LB->next;
 	LC=LA;
 	Linklist pc=LC;
 	LC->next =NULL;
 	while(pa&&pb)
 	{
 		if(pa->date<=pb->date)
 		{
 			LNode *p;
 			p=new LNode;
 			p->date  =pa->date;
 			p->next  =LC->next ;
 			LC->next =p;
 			pa=pa->next;
		 }
		 else
		 {
 			LNode *p;
 			p=new LNode;
 			p->date  =pb->date;
 			p->next  =LC->next ;
 			LC->next =p;
 			pb=pb->next;
		 }
	 }
	 while(pa) //鏈LA還有資料 
	 {
	 	LNode *p;
	 	p=new LNode;
	 	p->date =pa->date ;
	 	p->next =LC->next ;
	 	LC->next =p;
	 	pa=pa->next ;
	 }
	while(pb)  //鏈LB還有資料 
	 {
	 	LNode *p;
	 	p=new LNode;
	 	p->date =pb->date ;
	 	p->next =LC->next ;
	 	LC->next =p;
	 	pb=pb->next ;
	 }

	 delete LB;
     traverse(LC);
  } 
//第三題:C=A∩B    時間複雜度O(length(LA))
void  aggergate_3(Linklist &LA,Linklist &LB,Linklist &LC)
{
	Linklist pa=LA->next;
	Linklist pb=LB->next;
	LC=LA;
	Linklist pc=LC;
	pc->next =NULL;
	while(pa)
	{
		int flag=0;
		while(pb)
		{
			if(pa->date == pb->date)
		   {
		   	flag=1;
		   	break;	
		   }
		   else
		    pb=pb->next ;
	    }
	    if(flag==1)
	    {
	    	pc->next=pa;
		    pc=pa;	
		}
        	pa=pa->next;
        	pb=LB->next;
	} 
	pc->next =NULL;
	delete LB,LA;
}
//第四題:在集合A中出現而不在集合B中出現 時間複雜度O(length(LA)*length(LB))
void mergelist_4(Linklist &LA,Linklist &LB,Linklist &LC,int &s1)
{    //設兩個指標  一個pa 一個pb    pa移動一次pb跑一整趟,所以迴圈完記得還要把pa指到第一個節點上 
	s1=0;
	Linklist pa=LA;
	Linklist pb=LB;
    LC=LA;
    Linklist pc=LC;
    
	while(pa)
	{   
	    int p=0;
	    while(pb)
	    {
			if(pb->date==pa->date)
			{
			  pc->next=pa->next ;
			  p=1;
			} 
			pb=pb->next ;
		}
		if(p==0)  {
		    pc=pa ; 
		    s1++;
		}  
		pa=pa->next ;
		
		pb=LB->next ;
		
	}
    s1--;
	delete LB;
}
//第五題:拆分表A    時間複雜度O(length(LA))
void splitlist_5(Linklist &LA,Linklist &LB,Linklist &LC)
{    //坑 需另設兩個頭結點 
	Linklist pa=LA->next ;
	
	Linklist pb=LB;
    
    Linklist pc=LC;
    while(pa)
    { 
    	if(pa->date >0)
    	{
			LNode *p;
			p=new LNode;
			p->date=pa->date;
			p->next=NULL;
			pb->next=p;
			pb=p;
    		pa=pa->next;
		}
		else if(pa->date <0)
		{
            LNode *p;
			p=new LNode;
			p->date=pa->date;
			p->next=NULL;
			pc->next=p;
			pc=p;
			pa=pa->next;
		}
	}
 } 
 //第六題: 求鏈A中最大值   時間複雜度O(length(LA))
void Maxlist(Linklist L) 
{    //遍歷 
	LNode *p;
	p=L->next->next;
	int max=L->next->date;
	
	while(p)
	{
		max=max>p->date?max:p->date;
		p=p->next;
	}
	cout<<"該連結串列中的最大值為:"<<max<<endl<<endl; 
} 
//第七題: 逆轉連結串列   時間複雜度O(length(LA))
void reversal_7(Linklist &LA,Linklist &LB)
{   //設兩個指標一個向後跑一個用來前插法定位  
	Linklist pa=LA->next->next  ;
	LB=LA;
	Linklist pb=LB->next ;
	pb->next=NULL;  //要記得先把尾斷了 不然結果會出現 123321 
	while(pa)
	{   
	    LNode *p;
	    p=new LNode;
		p->date =pa->date ;
		p->next =pb ;
		LB->next =p;
		pb=p;
		pa=pa->next ;
	
	}
	
 } 
//第八題: 刪除鏈A中(mink,maxk) 範圍內的資料  時間複雜度O(length(LA))
void list_8(Linklist &LA,Linklist &LB,int a,int b)
{     //遍歷 
	Linklist pa=LA->next ;
	LB=LA;
	Linklist pb=LB;
	while(pa)
	{
		if(pa->date>a && pa->date<b)
		{
			pb->next =pa->next;
			pa=pa->next ;
		    
		}
		else
		{
			pb->next =pa;
			pb=pa;
			pa=pa->next ;
			
		}
	}
 } 
 //第九題: 交換雙向連結串列中a資料和它之前的元素 
 void change_9(DuLinklist &LA,int a)
 {  //a資料結點的前驅取出 插入到a之後 
 	DuLinklist p;
 	p=LA->next;
 	while(p->date!=a)
 	  p=p->next ;
 	
	     
 			DuLNode *q;
			q=new DuLNode;
 			q->date =p->prior->date;
 			q->next =NULL ;
 			
            p->prior->prior->next =p;
 			p->prior =p->prior->prior;
 			
 		if(p->next)	
		{
 			q->next =p->next ;
 			q->prior=p;
 			p->next=q;
 			q->next->prior=q;
		}
		else
		{
			p->next =q;
		}
	 
	 
 }
 //第十題: 刪除順序表中為a的數  時間複雜度O(length(LA))
void delete_10(SqList L,int a)
{      //定義兩個下標值在同一陣列空間一起跑 
	int p;
	p=0;
	for(int i=0;i<L.length ;i++)
	{
	    if(L.elem[i]!=a)
		  L.elem[p++]=L.elem[i];	
	 } 
	cout<<"結果為:"; 
	for(int i=0;i<p;i++)
	{
		cout<<L.elem [i]<<" ";
	}
	cout<<endl;
}
int main()
{

	cout<<"-------53頁課本習題-------"<<endl;	
	cout<<"1,第一題;"<<endl;
	cout<<"2,第二題;"<<endl;
	cout<<"3,第三題;"<<endl;
	cout<<"4,第四題;"<<endl;
	cout<<"5,第五題;"<<endl;
	cout<<"6,第六題;"<<endl;
	cout<<"7,第七題;"<<endl;
	cout<<"8,第八題;"<<endl; 
	cout<<"9,第九題;"<<endl; 
	cout<<"10,第十題;"<<endl; 
	cout<<"0,退出。"<<endl<<endl;
	int n;
	cout<<"請輸入需要驗證題目編號:";
	cin>>n;
	while(n)
	{	
          if(n==1)
          	  {
          	  	Linklist LA,LB; 
	            int LA_length,LB_length;
          	  	cout<<"請先建立兩個單鏈表!!!"<<endl;
                cout<<"請分別輸入單鏈表的長度:";
	            cin>>LA_length>>LB_length;
	            cout<<"請輸入第一個單鏈表的內容:";
                creatlist_d(LA,LA_length);
	            cout<<"請輸入第二個單鏈表的內容:";
                creatlist_d(LB,LB_length); 
          	  	Linklist LC;
          		mergelist_1(LA,LB,LC);
          		cout<<endl;
          		delete LA,LB,LC;
			  }
		   else if(n==2)
		   	   {
		   	   	Linklist LA,LB; 
	            int LA_length,LB_length;
          	  	cout<<"請先建立兩個單鏈表!!!"<<endl;
                cout<<"請分別輸入單鏈表的長度:";
	            cin>>LA_length>>LB_length;
	            cout<<"請輸入第一個單鏈表的內容:";
                creatlist_d(LA,LA_length);
	            cout<<"請輸入第二個單鏈表的內容:";
                creatlist_d(LB,LB_length);
		   	   	Linklist LC;
		   		mergelist_2(LA,LB,LC);
		   		cout<<endl; 
		   		delete LA,LB;
			   }
			else if(n==3)
				{
				Linklist LA,LB; 
	            int LA_length,LB_length;
          	  	cout<<"請先建立兩個單鏈表!!!"<<endl;
                cout<<"請分別輸入單鏈表的長度:";
	            cin>>LA_length>>LB_length;
	            cout<<"請輸入第一個單鏈表的內容:";
                creatlist_d(LA,LA_length);
	            cout<<"請輸入第二個單鏈表的內容:";
                creatlist_d(LB,LB_length);
				Linklist LC;
				aggergate_3(LA,LB,LC);
				traverse(LC);
				cout<<endl;
				delete LA,LB;
			   }
			else if(n==4)
				{
				Linklist LA,LB,pa=LA,pb=LB; 
	            int LA_length,LB_length;
          	  	cout<<"請先建立兩個單鏈表!!!"<<endl;
                cout<<"請分別輸入單鏈表的長度:";
	            cin>>LA_length>>LB_length;
	            cout<<"請輸入第一個單鏈表的內容:";
                creatlist_d(LA,LA_length);
	            cout<<"請輸入第二個單鏈表的內容:";
                creatlist_d(LB,LB_length);
			   	 Linklist LC;
			   	 int s1=0;
			     mergelist_4(LA,LB,LC,s1);
			     traverse(LC);
			     cout<<"該連結串列的長度為:"<<s1<<endl; 
			     cout<<endl;
			     delete LA,LB;
				}
			else if(n==5)
			   {
			 	Linklist LA;
				LNode *LB,*LC; 
				LB=new LNode;
				LC=new LNode;
				LB->next=NULL;
				LC->next=NULL;
	            int LA_length;
	            cout<<"請先建立一個單鏈表!!!"<<endl;
                cout<<"請輸入單鏈表的長度:";
	            cin>>LA_length;
	            cout<<"請輸入單鏈表的內容:";
                creatlist_d(LA,LA_length);
	            splitlist_5(LA,LB,LC);
	            traverse(LB);
	            traverse(LC);
				delete LA,LB,LC;
			   }
			 else if(n==6)
			   {
			   	Linklist LA; 
	            int LA_length;
	            cout<<"請先建立一個單鏈表!!!"<<endl;
                cout<<"請輸入單鏈表的長度:";
	            cin>>LA_length;
	            cout<<"請輸入單鏈表的內容:";
                creatlist_d(LA,LA_length); 
			   	Maxlist( LA) ;
			   	delete LA;
				 } 
			 else if(n==7)
			   {
			 	Linklist LA,LB; 
	            int LA_length;
	            cout<<"請先建立一個單鏈表!!!"<<endl;
                cout<<"請輸入單鏈表的長度:";
	            cin>>LA_length;
	            cout<<"請輸入單鏈表的內容:";
                creatlist_d(LA,LA_length); 
                reversal_7( LA, LB);
                traverse(LB);
                cout<<endl;
                delete LA;
				}
			else if(n==8)
			{
				Linklist LA,LB; 
	            int LA_length;
	            cout<<"請先建立一個單鏈表!!!"<<endl;
                cout<<"請輸入單鏈表的長度:";
	            cin>>LA_length;
	            cout<<"請輸入單鏈表的內容:";
                creatlist_d(LA,LA_length); 
                cout<<"請輸入刪除資料範圍:";
                int a,b;
                cin>>a>>b;
                list_8(LA,LB,a,b);
                traverse(LB);
                cout<<endl;
                delete LA,LB;
				 }	
			else if(n==9)
			  {
				DuLinklist LA;
				int LA_length;
	            cout<<"請先建立一個單鏈表!!!"<<endl;
                cout<<"請輸入單鏈表的長度:";
	            cin>>LA_length;
	            cout<<"請輸入單鏈表的內容:";
				creatlist_du( LA, LA_length) ;
				cout<<"請輸入要交換的後一個數據:";
				int a;
				cin>>a; 
				change_9(LA,a);
				traverse_d(LA);
			   } 
			else if(n==10)
			  {
			  	SqList LA;
                
				int LA_length;
				  
			 	cout<<"請先建立一個順序表!!!"<<endl;
                cout<<"請輸入順序表的長度:";
	            cin>>LA_length;
	            LA.length=LA_length;
	            cout<<"請輸入單鏈表的內容:";
	            for(int i=0;i<LA.length ;i++)
	            {
	            	cin>>LA.elem [i];
				}
				cout<<"請輸入需要刪除的資料:" ;
			    int a;
			    cin>>a;
			    delete_10(LA,a);
			    cout<<endl; 
			  } 
	cout<<"1,第一題;"<<endl;
	cout<<"2,第二題;"<<endl;
	cout<<"3,第三題;"<<endl;
	cout<<"4,第四題;"<<endl;
	cout<<"5,第五題;"<<endl;
	cout<<"6,第六題;"<<endl;
	cout<<"7,第七題;"<<endl;
	cout<<"8,第八題;"<<endl;
	cout<<"9,第九題;"<<endl; 
	cout<<"10,第十題;"<<endl; 
	cout<<"0,退出。"<<endl<<endl;
	//int n;
	cout<<"請輸入需要驗證題目編號:";
	cin>>n;	   
	} 
	 return 0;
}