单链表操作

//这一次补上链表的注释,代码是空闲的时候敲出来的,如果有错,希望帮忙纠正
//部分给出了详细说明,这里只选取了基本操作,因为更复杂的链表操作太繁琐,这里就不写了
//如果有什么不懂的地方,可以随时询问

 

#include <iostream>
using namespace std;
typedef int Elemtype; 

struct Node
{
	Elemtype data;
	Node *next;
};

void Init(Node **L)  //主函数里面定义Node型指针变量plist,储存单链表的头指针
{
	//Node *L;
//	L=new Node;
	*L=NULL;       
	cout<<"初始化成功!\n";
}
//初始化函数形参要给二级指针,相应的主函数里面实参则是对头指针的引用

void Clear_List(Node *head)  //清空函数
{
	Node *flag;
	if(head==NULL)
	{
		cout<<"链表为空!\n";
		return;
	}
	while(head->next!=NULL)
	{
		flag=head->next;
		delete(head);
		head=flag;
	}
	cout<<"链表已经清空!\n";
}
//加一个标记,移动头指针后赋值flag保存下一个位置,然后删除当前节点

Node *Creat_list(Node *head)  //赋值函数
{
	//int n=0;
	Node *p1,*p2;
	p1=new Node;
	p2=new Node;
	//head=NULL;
	cout<<"请输入链表元素,以0结束输入:"<<endl;
	cin>>p1->data;
	p1->next=NULL;
	while(p1->data!=0)
	{
		//n=n+1;
		//if(n==1)
		if(head==NULL)
			head=p1;
		else
			p2->next=p1;
		p2=p1;
		p1=new Node;
		cin>>p1->data;
		p1->next=NULL;
	}
	
	//cout<<head->data;
	return head;
}
//读入链表元素,在while循环里面每次将当前指针保存下来,然后不断向后更新

void List_length(Node *head)
{
	int i=0;
	while(head!=NULL)
	{
		i++;
		head=head->next;
	}
	cout<<"链表长度length: "<<i<<endl;
}

void Out_list(Node *head)
{
//	cout<<head->data;
	if(head==NULL)
		cout<<"链表为空!\n";
	else
	{
		while(head!=NULL)
		{
			cout<<head->data<<" ";
			head=head->next;
		}
		cout<<endl;
	}
}

Elemtype Get_elem(int index,Node *head) //给定下标,求节点元素
{
	int j=0;
	//Node *p;
	while(head!=NULL)
	{
		j++;
	    if(j==index)
			break;
		head=head->next;
	}
	if(j<index)
	{
		cout<<"选取的范围超出链表长度!\n";
		return 0;
	}
	return head->data;
}
//给定的下标index,只需遍历链表,当节点数符合要求时即可


int locate_elem(Node *head,Elemtype _First)  //给定节点元素,求第一个下标(也可以扩展求多个点的下标)
{
	int n=1;
	while(head!=NULL)
	{
		if(head->data==_First)
			return n;
		else
			n++;
		head=head->next;
	}
	cout<<"单链表里不存在这个元素!\n";
}
//同理,遍历查找出给定元素,然后直接返回下标

bool Insert_elem(Node *head,Elemtype insert_elem,int index)
{
	Node *p,*q;
	if(index<1)
	{
		cout<<"输入下标有误!\n";
		return false;
	}
	int i=1;
	while(head!=NULL)
	{
		i++;
		head=head->next;
		if(i==index-1)
		{
			p=q=new Node;
			q=head;
			//head=head->next;
			(*p).data=insert_elem;  
			//这里调试了好久。。。开始我是想定义一个节点和一个指针的,输出的时候会报错
			//最后还是觉得都定义指针吧,p那里不加括号的话也会报错
			(*p).next=head->next;
			q->next=p;
			//p->next=head->next;
			//p->data=insert_elem;
			return true;
		}
	}
	return false;
}
//插入步骤稍微多些,要另外定义两个指针,思路就是遍历到给定下标的前一个下标,同时指针q记录下位置
//而另外一个指针p储存节点数据,并且使它指向头指针下一个点的地址,最后使q指向p即可


bool delete_Node(Node *head,int index)
{
	int i=1;
	if(index<1)
	{
		cout<<"输入下标值有误!\n";
		return false;
	}
	while(head!=NULL)
	{
		i++;
		head=head->next;
		if(i==index-1)
		{
			Node *p;
			p=new Node;
			p=head;
			head=head->next;
			p->next=head->next;
			return true;
		}
	}
	return false;
}
//操作类似于插入,不多说

bool Change_Node_Elem(Node *head,int index,Elemtype Example3)
{
	int i=1;
	if(head==NULL||index<1)
	{
		cout<<"输入错误或链表为空!\n";
		return false;
	}
	while(head!=NULL)
	{
		i++;
		head=head->next;
		if(i==index)
		{
			head->data=Example3;
			return true;
		}
	}
	return false;
}
//也是遍历链表找到给定位置,然后更新数据

int main()
{
	//Node *plist=NULL;
	Node *plist;
	Elemtype Example1=5,Example2=7,Example3=9;
	cout<<"创建一个单链表(plist):\n";
	Init(&plist);     //初始化
	plist=Creat_list(plist);  //创建单链表,给单链表赋值,返回头指针

	cout<<"打印原始链表:\n";
	Out_list(plist);
	cout<<endl;

	cout<<"链表第三个节点的元素值为: "<<Get_elem(3,plist)<<endl; 
	cout<<endl;
	//调用Get_elem函数,返回链表第三个节点内元素值

	//cout<<"输出链表长度:\n";
	List_length(plist);
	cout<<endl;

	cout<<"链表plist第一次出现 "<<Example1<<" 值的下标:"<<locate_elem(plist,Example1)<<endl; 
	cout<<endl;
	//调用locate_elem函数,返回链表内第一个出现Example1元素的节点数

	
	cout<<"将元素 "<<Example2<<" 插入链表第四个节点上:"<<endl;
	if(Insert_elem(plist,Example2,4))
		cout<<"Insert is OK!\n";
	else
		cout<<"Insert is not OK!\n";
	cout<<"改变后的链表为:"<<endl;
	Out_list(plist);
	cout<<endl;


	cout<<"将链表第七个节点删除:"<<endl;
	if(delete_Node(plist,7))
		cout<<"Delete is OK!\n";
	else
		cout<<"Delete is not OK!\n";
	cout<<"改变后的链表为:"<<endl;
	Out_list(plist);
	cout<<endl;


	cout<<"将链表plist中第三个节点的元素换成 "<<Example3<<endl;
	if(Change_Node_Elem(plist,3,Example3))
	{
		cout<<"改变后的链表为:\n";
		Out_list(plist);
	}
	else
		cout<<"数值改变失败!\n";
	cout<<endl;

	cout<<"执行清空函数:"<<endl;
	Clear_List(plist);
	return 0;
}


 

posted @ 2014-12-11 12:44  __夜风  阅读(147)  评论(0编辑  收藏  举报