单链表的一些操作

/*
构造一个带头节点的空链表1.1为单链表的指针、头指针可以标志一个
确定的单链表,算法中1前的"&"表示该变量是指针的指针的类型,实现时用*表示
*/


#include <iostream>
using namespace std;



/*
描述一个单链表
*/

typedef struct node
{
	int data;             //定义存储整形数据
	struct node *next;    //定义存储下一个数据位置的指针
}node, *linkList;


/*
首先初始化一个链表
*/
int Initlist (linkList &a)
{
	if ( (a = (node*)malloc(sizeof(node))) == NULL)
		return 0;
	else
	{
		a->next =NULL;
		return 1;
	}
}


/*
建立一个链表。类似于往栈中存放数据。p为动态指针,始终指向未分配数据的最顶端。
head为链表的头指针,头指针值指向链表中第一个元素的存储地址。
*/
node* Create()
{
	node *head =  (node*)malloc(sizeof(node));//定义指向结构体的头指针
	node *p;
	node *s;
	
	int x;
	int cycle = 1;
	
	p = head; //把头指针指向p
	while(cycle)
	{
		cout<<"Please input the data"<<endl;
		cin>>x;                             //每输入一次数据
		if(x!=0)
		{
			s = (node*)malloc(sizeof(node));//分配一个内存地址
			s->data = x;                    //把输入的数据传入到s所指向的地址中去
			cout<<x;
			p->next = s;                    //把分配的(指向该数据x的)内存地址保存到上一个数据的next指针中去
			p = s;                          //让指针p重新指向当前位置
		}
		else
			cycle = 0;
		
	}
	head = head->next;                      //head
	p->next = NULL;                         //把最后一个数据的指针赋值为NULL
	cout<<head->data;//最先传进去的值
	return (head);//返回
}


/*
单链表测长,掌握结构体作为形参的传参方式
*/
int length(struct node *head)
{
	int n = 0;
	struct node *p;
	p = head;
	while(p!=NULL)
	{
		p = p->next;
		n++;
	}
	return (n);
}


/*
单链表打印
*/
void prient(struct node *head)
{
	struct node *p;
	int n;
	n = length(head);//获得链表的长度
	p = head;
	if(head != NULL)
		while(p!=NULL)
		{
			cout<<p->data;
			p=p->next;
		}
}

/*
单链表删除一个节点.分为两种情况,一是删除的是头结点;二是删除节点
*/
node* deleteNode(struct node *head,int num)
//num为要删除的链表中的元素
{
	struct node *p;
	struct node *pFollow;
	p = head ;
	
	//找到需要删除的那个数,并且需要在链表的长度内
	while(num!=p->data && p->next !=NULL)
	{
		pFollow = p;
		p = p->next;
	}

	if(p->data ==num)
	{
		//如果删除的为第一个节点
		if(p ==head)
		{
			head = p->next;
			free(p);
		}
		//否则
		else
		{
			pFollow->next = p->next;
			free(p);
		}
	}
		
		return (head);
}


/*
单链表的插入
插入算法有多种,比如(1)在某个数据之后插入一个新的元素
                    (2)在第i-1和i个数据之后插入一个新的元素
					(3)在递增/减有序表中插入一个新的元素,使得生成的长度为n+1的表仍然是有序的

这里只是介绍第(2)中算法
*/
node* InsertList(struct node *head, int i, int elem)
// i 要插入的元素的位置;elem 要插入的元素
{
	struct node *p;
	struct node *s;
	s = (node*)malloc(sizeof(node));//生成一个新的节点
	p = head;
	int j = 0;//计数器

	//如果插入的是在头节点
	while(p->next != NULL && i != j)
	{
		p = p->next;  //指向下一个节点
		j++; 
	}
	//找到要插入的元素的位置
	s->data = elem;  //将新的元素插入到数据区域中
	s->next =p->next;//将上一个节点指针赋值到新的指针区域
	p->next =s;
	return (head);
}

/*
单链表的清空
*/
node* CleanList(struct node* head)
{
	struct node* p;
	p = head;
	while(p->next!= NULL)
	{
		p= p->next;
		free(p);
	}
	return (head);
}


/*
单链表的排序。将所有的数据按有大到小的顺序重新排列,并从新输出
*/

node* SortList(struct node* head)
{
	struct node *p;
	
	int temp;
	p = head;
	//获得链表的长度
	int n = length(head);

	if(head ==NULL || head->next ==NULL)
	{
		return head;

	}
	for(int i = 1;i<n;i++) //n-1次
	{
		p = head;
		for (int j =0;j<n-i;j++) //n-i次
		{
			if( (p->next)->data < p->data) //后者大于前者
			{
				temp = p->data; 	//交换值
				p->data = (p->next)->data;
				(p->next)->data = temp;
				
			}
			p = p->next; //指向下一个地址
		}
	}
	return (head);
}

/*
单链表的逆置
*/
node* InverseList(struct node* head)
{
	struct node *p;
	p = head;
	int temp;
	int n = length(head);
	for (int i = 1;i<n;i++) //n-1次
	{
        p = head;
		for(int j = 0;j<n-i; j++)
		{
			temp = p->data;
			p->data = p->next->data;
			p->next->data = temp;

			p = p->next;
		}
		
	
	}
	return (head);
}



void main()
{
	struct node *testNode;
	struct node *newNode;
	struct node *tnewNode;
	struct node *knewNode;

	//创建一个链表
	testNode = Create();

	cout<<"输出该结构体数组的长度"<<endl;

	cout<<length(testNode)<<endl;

	prient(testNode);
    //删除一个元素
	newNode=deleteNode(testNode,5);

	cout<<endl;

	prient(newNode);
    //插入一个新的元素
	InsertList(newNode, 3, 100);

	cout<<endl;

	prient(newNode);
	//排序(有小到大)
 	tnewNode=SortList(newNode);
 	cout<<endl;
	prient(tnewNode);

	//逆序输出
	knewNode=InverseList(tnewNode);

	cout<<endl;
	prient(knewNode);


}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值