1. 程式人生 > >連結串列的基本操作函式演算法(C/C++實現)

連結串列的基本操作函式演算法(C/C++實現)

連結串列的基本操作函式,一般的資料結構的書籍中涉及到的連結串列的基本操作演算法都實現了

#include <cstdlib>
#include <iostream>
#include <cstdio>
using namespace std;
typedef struct NODE{
	struct NODE *link;
	int value;
}Node;

#define TRUE 1
#define FALSE 0
bool search_val(Node *head,int val);
Node *get_node(Node *head,int val);
int count_list(Node *head);
bool is_empty(Node *head);
Node *get_last_node(Node *head);
void destroy_list(Node **rootp);
//有些函式的宣告沒寫在前面,請注意!
int node_insert(Node **rootp,int new_value){
	if(search_val(*rootp,new_value)) return TRUE;//如果有重複元素就不用插入了
	Node *previous;
	Node *current;
	Node *new_node;

	current=*rootp;//rootp指向連結串列首指標,是個二階指標
	while(current!=NULL && current->value < new_value){//尋找待插入的位置
		previous=current;
		current=current->link;
	}
	//if(current->value==new_value) return TRUE;//???奇怪的bug

	new_node=(Node *)malloc(sizeof(Node));
	if(new_node==NULL){//如果new失敗了
		return FALSE;
	}

	new_node->value=new_value;
	new_node->link=current;
	if(previous==NULL){//如果待插入的元素最小,即要把new出來的結點放到連結串列首部
		*rootp=new_node;
	}else{//否則正常連線
		previous->link=new_node;
	}
	return TRUE;
}

int node_insert(Node *head,int val){
	Node *t=(Node *)malloc(sizeof(Node));
	if(t==NULL) return FALSE;
	t->value=val;
	t->link=NULL;
	if(head==NULL){
		head=t;
		return TRUE;
	}
	Node *p=get_last_node(head);
	if(p==NULL){
		return FALSE;
	}else{
		p->link=t;
	}
	return TRUE;
}

int node_delete(Node **rootp,int val){
	if(!search_val(*rootp,val)) return FALSE;//如果沒有待刪除元素就直接返回
	Node *previous=NULL;//previous的初始值是必要的,但要刪除的是頭結點時,用於判斷
	Node *current;
	current=*rootp;//rootp指向連結串列首指標,是個二階指標
	while(current!=NULL && current->value!=val){//尋找待刪除的位置,前面已經保證了一定有待刪除元素
		previous=current;
		current=current->link;
	}
	//迴圈結束後就找到了待刪除結點的位置current
	if(previous==NULL){//如果要刪除的是頭節點
		*rootp=current->link;
		free(current);
		current=NULL;
	}else{
		previous->link=current->link;//如果要刪除的是尾結點,current->link就是NULL,就相當於設定了終止標誌
		free(current);
		current=NULL;
	}
	return TRUE;

}

void show_linklist(Node *head){
	Node *p=head;
	while(p!=NULL){
		cout<<p->value<<"->";
		p=p->link;
	}
	cout<<"NULL"<<endl;
}

bool search_val(Node *head,int val){
	Node *p=head;
	while(p!=NULL){
		if(p->value==val){
			return true;
		}
		p=p->link;
	}
	return false;//沒找到
}

Node *get_last_node(Node *head){
	Node *p=head;
	Node *previous=NULL;
	while(p!=NULL){
		previous=p;
		p=p->link;
	}
	return previous;
}

Node *reverse_list(Node **rootp){
	if(*rootp==NULL) return NULL;
	int len=count_list(*rootp)-1;
	int vals[len];
	Node *p=*rootp;

	Node *t=(Node *)malloc(sizeof(Node));
	t->value=get_last_node(*rootp)->value;
	t->link=NULL;

	Node *root=t;
	int i=0;
	while(p!=NULL){
		vals[i++]=p->value;
		p=p->link;
	}
	for(i=0;i<len;++i){
		node_insert(root,vals[len-1-i]);
	}
	destroy_list(rootp);
	return root;
}

Node *get_node(Node *head,int val){
	Node *p=head;
	while(p!=NULL){
		if(p->value==val){
			return p;
		}
		p=p->link;
	}
	return NULL;//沒找到
}

bool is_empty(Node *head){
	if(head==NULL){
		return true;
	}else{
		return false;
	}
}

int count_list(Node *head){
	Node *p=head;
	int cnt=0;
	while(p!=NULL){
		++cnt;
		p=p->link;
	}
	return cnt;
}

void destroy_list(Node **rootp){//刪除整個連結串列
	if(*rootp==NULL) return;
	Node *p=get_last_node(*rootp);
	while(p!=NULL){
		node_delete(rootp,p->value);
		p=get_last_node(*rootp);
	}
}

void test(){//測試函式
	Node t;
	t.value=20;
	t.link=NULL;
	Node *root=&t;
	for(int i=15;i<=25;++i){
		node_insert(&root,i);
	}
	cout<<root->value<<endl;
	show_linklist(root);
	cout<<search_val(root,20)<<endl;
	cout<<node_delete(&root,12)<<endl;
	show_linklist(root);
	cout<<node_delete(&root,20)<<endl;
	cout<<node_delete(&root,25)<<endl;
	cout<<node_delete(&root,15)<<endl;
	show_linklist(root);
	cout<<count_list(root)<<endl;
	cout<<get_last_node(root)->value<<endl;

	root=reverse_list(&root);
	cout<<root->value<<endl;
	show_linklist(root);
	destroy_list(&root);
	show_linklist(root);
	cout<<(root==NULL)<<endl;
}

int main(){
    test();
    return 0;
}