1. 程式人生 > >帶有頭結點的單向迴圈連結串列

帶有頭結點的單向迴圈連結串列

題目:

        建立帶有頭結點的迴圈連結串列,實現插入 、查詢 、 刪除等功能 。

原始碼:

#include<iostream>
#include<malloc.h>
using namespace std;
typedef int elemtype; //定義結點型別 

//定義一個線性連結串列的型別
typedef struct node
{
	elemtype data; //資料域
	struct node *next; //指標域 
}node,*linklist;

//初始化連結串列 
linklist initlist()
{
	node *p;
	p = (node*)malloc(sizeof(node));
	if(p == NULL)
		cout<<"申請記憶體空間失敗!"<<endl<<endl;
	else
	{
		p->next = NULL;
		cout<<"初始化成功!"<<endl<<endl; 
	}
}

//知曉長度建立連結串列
linklist creat(linklist list)
{
	node *p,*q;
    p = list;                          	  
	elemtype a,n; 
	cout<<"輸入長度:";
	cin>>n;
	cout<<"輸入元素:";                        
    while(n--)
    {
    	q=(node*)malloc(sizeof(node));
        scanf("%d",&q->data);
        q->next = NULL;
        p->next = q;
        p = q;
    } 
    return list;
} 

//不知曉長度建立連結串列
linklist creat1(linklist list)
{
	node *p,*q;
    p = list;                          	  
	elemtype a; 
	//以0為結束的標記 
	cout<<"輸入元素:";                        
    while(cin>>a)
    {
    	if(a == 0)
    		break;
    	q=(node*)malloc(sizeof(node));
        q->data = a;
        q->next = NULL;
        p->next = q;
        p = q;
    } 
    return list;
} 
//求線性連結串列的長度
int length1(linklist list)
{
	linklist p = list;
	int n = 0;
	while(p!=NULL)
	{	
		n++;//計數器累加 
		p = p->next; //指標p指向下一個鏈結點 
	}
	return n;//返回連結串列的長度 
} 

//求線性連結串列的長度(遞迴)
int length2(linklist list)
{
	if(list!=NULL)
		return 1+length2(list->next);
	else
		return 0; 
} 

//確定元素item線上性連結串列中的位置
linklist find(linklist list,elemtype item)
{
	linklist p = list;
	int place = 1;
	while(p !=NULL && p->data != item)
	{
		place++;
		p = p->next;
	}
	if(p !=NULL && p->data == item)
		cout<<"item的位置為:"<<place<<endl;
	else
		cout<<"item不存在!"<<endl;
}

//非空線性連結串列的末尾插入一個數據信息為item的連結點
void insert1(linklist list,elemtype item)
{
	//list存放連結串列的首地址
	linklist p,r;
	r = list;
	while(r->next!=NULL)
		r = r->next;//找到連結串列末尾結點的地址 
	p = (linklist)malloc(sizeof(node));//申請一個新的連結點
	p ->data = item;//將item送新結點的資料域
	p ->next = NULL;//新結點的指標域置為NULL 
	r ->next =p;//插入連結串列的末尾 
}


//線上性連結串列中的第i個鏈結點後面插入一個數據信息為item的連結點
void insert2(linklist list,int i,elemtype item)
{
	linklist p,q = list;
	int j=1;
	while(j<i&&q!=NULL)
	{
		q = q ->next;
		j++; 
	}//尋找第i個鏈結點
	if(j!=i||q==NULL)
		printf("連結串列中不存在第i個鏈結點");
	p = (linklist)malloc(sizeof(node));//申請一個新的鏈結點
	p ->data = item;//將item送新結點的資料域
	p ->next = q ->next;
	q ->next = p;//將新結點插入第i個鏈結點之後
}

//在按值有序連結的線性連結串列中插入一個數據信息為item的鏈結點
linklist insert3(linklist &list,elemtype item)
{
	linklist p,q,r;
	p = (linklist)malloc(sizeof(node));
	p ->data = item;
	if(list==NULL||item<list->data)//若連結串列為空或者item小於第1個鏈結點 
	{
		p ->next = list;//將新的鏈結點插在連結串列最前面 
		list = p;//list指向被插入的新結點 
	}	
	else
	{
		q = list;
		while(q!=NULL&&item>=q->data)//尋找插入位置 
		{
			r = q;
			q = q->next;
		}
		p->next = q;
		r->next = p;//將新的鏈結點插在q指示的鏈結點後面 
	} 
	return list;
}

//逆轉一個線性連結串列
void invert(linklist &list)
{
	linklist p,q,r;
	p = list;
	q = NULL;
	while(p!=NULL)
	{
		r = q;
		q = p;
		p = p->next;
		q->next = r;
	}
	list = q;
} 

node* getelem(linklist list,int k)
{
    node* s=list;
    while(k)
    {
        s=s->next;
        k--;
    }
    return s;
}

void deletelist3(linklist list,int k)
{
    node* p=list;
    node* q=NULL;
    p=getelem(list,k-1);
    q=p->next;
    p->next=q->next;
    free(q);

}

//銷燬一個線性連結串列
void deletelist(linklist &list)
{
	linklist p = list;
	while(p!=NULL)
	{
		list = p->next;//儲存下一個鏈結點的位置
		free(p);//刪除並釋放當前的鏈結點
		p = list;//下一個鏈結點成為當前鏈結點
	}
} 

//列印連結串列元素,遍歷連結串列 
void printinfo(linklist list)
{
	node *head;
	if(head == NULL)//連結串列為空   
		cout<<"連結串列為空!"<<endl;
	//連結串列不為空則輸出打印出元素 
	else 
	{
		cout<<"連結串列元素為:";
		for(head=list;head!=NULL;head=head->next)//第一個元素指向list  
			cout<<head->data<<" ";
		cout<<endl<<endl;
	}
}

int main()
{
	linklist list;
	elemtype n,item,i;
	
	//初始化連結串列
	cout<<"初始化連結串列!"<<endl; 
	list = initlist();
	
	//建立頭結點
	list = (node*)malloc(sizeof(node));
    list->next = NULL;
    list->data = -1; 
	
	//建立連結串列(知曉長度) 
	cout<<"建立連結串列!"<<endl;
	list = creat(list); 
	printinfo(list);
	
	//建立連結串列(不知曉長度) 
	cout<<"建立連結串列,以0為結束標誌!"<<endl; 
	list = creat1(list); 
	printinfo(list);
	
	//求連結串列的長度
	cout<<"連結串列的長度!"<<endl<<"連結串列長度為:"<<length1(list)<<endl;
	
	//求連結串列的長度
	cout<<"連結串列的長度!"<<endl<<"連結串列長度為:"<<length2(list)<<endl;
	
	//確定元素item線上性連結串列中的位置
	cout<<endl<<"元素item的位置!"<<endl;
	cout<<"輸入元素item:";
	cin>>item; 
	find(list,item); 
	
	//非空線性連結串列的末尾插入一個數據信息為item的連結點	
	cout<<endl<<"末尾插入item結點!"<<endl;
	cout<<"輸入元素item:";
	cin>>item; 
	insert1(list,item); 
	printinfo(list); 
	
	//線上性連結串列中的第i個鏈結點後面插入一個數據信息為item的連結點
	cout<<endl<<"第i個鏈結點後面插入item!"<<endl;
	cout<<"輸入結點i:";
	cin>>i; 
	cout<<"輸入元素item:";
	cin>>item; 
	insert2(list,i,item);
	printinfo(list);
	
	//在按值有序連結的線性連結串列中插入一個數據信息為item的鏈結點
	cout<<endl<<"按值有序在連結串列中插入item!"<<endl;
	cout<<"輸入元素item:";
	cin>>item; 
	insert3(list,item);
	printinfo(list);
	
	//逆轉一個線性連結串列
	cout<<endl<<"逆序連結串列!"<<endl; 
	invert(list);
	printinfo(list);
	invert(list);
	printinfo(list);
	
	//刪除第i個結點
	cout<<endl<<"刪除第i個結點!"<<endl; 
	cout<<"輸入結點i:";
	cin>>i; 
	deletelist3(list,i);
	printinfo(list); 
	
	//銷燬一個線性連結串列
	cout<<endl<<"銷燬連結串列!"<<endl; 
	deletelist(list);
	printinfo(list);
	return 0;
}