1. 程式人生 > >線性表的鏈式儲存結構的基本操作(經編譯)

線性表的鏈式儲存結構的基本操作(經編譯)

/* 連結串列銷燬的時候,是先銷燬了連結串列的頭,然後接著一個一個的把後面的結點銷燬了,這樣這個連結串列就不能再使用了。 連結串列清空的時候,是先保留了連結串列的頭,然後把頭後面的所有的結點都銷燬,最後把頭裡指向下一個的指標設為空,這樣就相當與清空了,但這個連結串列還在,還可以繼續使用*/

#include<iostream>		 
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
using namespace std;

#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define OVERFLOW -2
#define MAXSIZE 20


typedef int ElemType;

typedef struct LNode {
	ElemType data;
	struct LNode *next;
} LNode;

typedef struct LNode *LinkList;			
//初始化或重置連結串列
int ResetList(LinkList *L) { 
	LinkList p,q;
	p=(*L)->next;
	while(p) {
		q=p->next;
		free(p);
		p=q;
	}
	(*L)->next=NULL;
	cout<<"重置成功!"<<endl;
	return OK;
}
//銷燬連結串列
int DestroyList(LinkList *L) {
	if(!(*L)) {
		cout<<"連結串列不存在!"<<endl;
		return FALSE;
	} else {
		LinkList q;
		while(*L) {
			q=(*L)->next;
			free(*L);
			*L=q;
		}
		cout<<"銷燬成功!"<<endl;
		return OK;
	}
}

//連結串列中資料元素個數
int ListLength(LinkList L) {
	if(!L) {
		cout<<"連結串列不存在!"<<endl;
		return FALSE;
	} else {
		LinkList e;
		int num=0;
		e=L->next;
		while(e) {
			num++;
			e=e->next;
		}
		return num;
	}
}

//所指位序的元素值
int GetElem(LinkList L,int locate,ElemType *e) {
	int j=1;
	LinkList p;
	p=L->next;
	while(p && j<locate) {
		p=p->next;
		++j;
	}
	if( !p || j>locate) {
		cout<<"該位序不存在!"<<endl;
		return ERROR;
	}
	*e=p->data;
	cout<<"第"<<locate<<"個元素為:"<<*e<<endl;
	return OK;
}
//連結串列已存在元素的位序
int LocateElem(LinkList L,ElemType e) {
	int i=0;
	LinkList p=L->next;
	while(p) {
		i++;
		if( p->data == e )	return i;
		p=p->next;
	}
	return ERROR;
}
//請輸入元素,求直接前驅
int PriorElem(LinkList L,ElemType cur_e,LinkList *pre_e) {
	*pre_e=L->next;
	int a,num=1;
	a=LocateElem(L,cur_e);
//	cout<<a<<endl;
	if(a==0) {
		cout<<"元素"<<cur_e<<"不存在!"<<endl;
		return OVERFLOW;
	} else if(a==1) {
		cout<<"元素"<<cur_e<<"沒有前驅!"<<endl;
		return OVERFLOW;
	} else {
		while(pre_e && num<(a-1)) {
			*pre_e=(*pre_e)->next;
			++num;
		}
		if(num==(a-1)) {
			cout<<"元素"<<cur_e<<"的前驅為:"<<(*pre_e)->data<<endl;
			return OK;
		}
	}
}
//請輸入元素,求直接後繼
int NextElem(LinkList L,ElemType cur_e, LinkList next_e) {
	next_e=L->next;
	int a,num=1;
	a=LocateElem(L,cur_e);
//	cout<<ListLength(L)<<endl;
	if(a==0) {
		cout<<"元素"<<cur_e<<"不存在!"<<endl;
		return OVERFLOW;
	} else if(a==ListLength(L)) {
		cout<<"元素"<<cur_e<<"沒有後驅!"<<endl;
		return OVERFLOW;
	} else {
		while(next_e && num<(a+1)) {
			next_e=next_e->next;
			++num;
		}
		if(num==(a+1)) {
			cout<<"元素"<<cur_e<<"的後驅為:"<<next_e->data<<endl;
		}
	}
	return OK;
}
//在第i個位置插入元素
int ListInsert(LinkList *L,int i,ElemType e) {
	int j;
	LinkList p,s;
	p = *L;
	j = 1;
	while (p && j < i) {
		p = p->next;
		++j;
	}
	if (!p || j > i) {
		cout<<"插入失敗!"<<endl;
		return ERROR;
	}
	s = (LinkList)malloc(sizeof(LNode));
	s->data = e;
	s->next = p->next;      /* 將p的後繼結點賦值給s的後繼  */
	p->next = s;          /* 將s賦值給p的後繼 */
	cout<<"插入成功!"<<endl;
	return OK;
}

//刪除第i個元素
int ListDelete(LinkList *L,int i,ElemType *e) {
	int j;
	LinkList p,q;
	p = *L;
	j = 1;
	while (p->next && j < i) {
		p = p->next;
		++j;
	}
	if (!(p->next) || j > i) {
		cout<<"刪除失敗!"<<endl;
		return ERROR;
	}
	q = p->next;
	p->next = q->next;			/* 將q的後繼賦值給p的後繼 */
	*e = q->data;               /* 將q結點中的資料給e */
	free(q);                    /* 讓系統回收此結點,釋放記憶體 */
	cout<<"刪除成功!"<<endl;
	return OK;
}

//輸出所輸入的連結串列元素
int ListTraverse(LinkList L) {
	if(!L) {
		cout<<"連結串列不存在!"<<endl;
		return FALSE;
	} else {
		LinkList e;
		e=L->next;
		while(e) {
			cout<<e->data<<" ";
			e=e->next;
		}
		cout<<endl;
		return OK;
	}
}

//初始化並輸入連結串列元素(尾插法!!!!!)
int InitList(LinkList *L) {
	LinkList rear,p;
	(*L)=(LinkList)malloc(sizeof(LNode));
	if(!(*L)) {
		cout<<"初始化失敗!"<<endl;
		return ERROR;
	}
	rear=*L;
	int num;
	while(scanf("%d",&num) != EOF ) {
		if(num<0)  break;
		p=(LinkList)malloc(sizeof(LNode));
		p->data=num;
		rear->next=p;
		rear = p;
	}
	rear->next=NULL;
	return OK;
}


int main() {

	LinkList L=NULL,pre_e,next_e;
	int locate;
	ElemType e,cur_e;

	cout<<"可執行操作有:" <<endl;
	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.在第i個位置插入元素    *******************"<<endl;
	cout<<"*************   9.刪除第i個元素          *******************"<<endl;
	cout<<"*************   10.輸出所輸入的連結串列元素  *******************"<<endl;
	cout<<"*************   11.初始化並輸入連結串列元素  *******************"<<endl;
	cout<<"*************   12.退出                  *******************"<<endl;
	cout<<"************************************************************"<<endl;
	cout<<endl<<"請輸入你的選擇:";
	int num;
	while(scanf("%d",&num)!= EOF) {
		switch(num) {
			case 1:
				if(!L) {
					cout<<"連結串列不存在!"<<endl;
					cout<<endl<<"請輸入你的選擇:";
					break;
				} else {
					ResetList(&L);
					cout<<"請輸入連結串列元素(以一個負數結尾):";
					InitList(&L);
					cout<<endl<<"請輸入你的選擇:";
					break;
				}
			case 2:
				DestroyList(&L);
				cout<<endl<<"請輸入你的選擇:";
				break;
			case 3:
				if(!L) {
					cout<<"連結串列不存在!"<<endl;
					cout<<endl<<"請輸入你的選擇:";
					break;
				} else {
					cout<<"連結串列中資料元素個數為:"<<ListLength(L)<<endl;
					cout<<endl<<"請輸入你的選擇:";
					break;
				}
			case 4:
				if(!L) {
					cout<<"連結串列不存在!"<<endl;
					cout<<endl<<"請輸入你的選擇:";
					break;
				} else {
					cout<<"請輸入一個位序數:";
					cin>>locate;
					GetElem(L,locate,&e);
					cout<<endl<<"請輸入你的選擇:";
					break;
				}
			case 5:
				if(!L) {
					cout<<"連結串列不存在!"<<endl;
					cout<<endl<<"請輸入你的選擇:";
					break;
				} else {
					cout<<"請輸入需要查詢的元素:";
					cin>>e;
					cout<<"元素"<<e<<"的位序為:"<<LocateElem(L,e)<<endl;
					cout<<endl<<"請輸入你的選擇:";
					break;
				}
			case 6:
				if(!L) {
					cout<<"連結串列不存在!"<<endl;
					cout<<endl<<"請輸入你的選擇:";
					break;
				} else {
					cout<<"請輸入需要查詢前驅的元素:";
					cin>>cur_e;
					PriorElem(L,cur_e,&pre_e);
					cout<<endl<<"請輸入你的選擇:";
					break;
				}
			case 7:
				if(!L) {
					cout<<"連結串列不存在!"<<endl;
					cout<<endl<<"請輸入你的選擇:";
					break;
				} else {
					cout<<"請輸入需要查詢後驅的元素:";
					cin>>cur_e;
					NextElem(L,cur_e,next_e);
					cout<<endl<<"請輸入你的選擇:";
					break;
				}
			case 8:
				if(!L) {
					cout<<"連結串列不存在!"<<endl;
					cout<<endl<<"請輸入你的選擇:";
					break;
				} else {
					cout<<"請輸入需要插入的位序和元素:";
					cin>>locate>>e;
					ListInsert(&L,locate,e);
					cout<<endl<<"請輸入你的選擇:";
					break;
				}
			case 9:
				if(!L) {
					cout<<"連結串列不存在!"<<endl;
					cout<<endl<<"請輸入你的選擇:";
					break;
				} else {
					cout<<"請輸入需要刪除的位序:";
					cin>>locate;
					ListDelete(&L,locate,&e);
					cout<<endl<<"請輸入你的選擇:";
					break;
				}
			case 10:
				if(!L) {
					cout<<"連結串列不存在!"<<endl;
					cout<<endl<<"請輸入你的選擇:";
					break;
				} else {
					cout<<"該連結串列元素為:";
					ListTraverse(L);
					cout<<endl<<"請輸入你的選擇:";
					break;
				}
			case 11:
				cout<<"請輸入連結串列元素(以一個負數結尾):";
				InitList(&L);
				cout<<endl<<"請輸入你的選擇:";
				break;
			case 12:
				return 0;
				break;
			default:
				cout<<"該資料無效,請重新輸入:";
				break;
		}
	}
	return 0;		 
}