单链表的增删查改,以及双向链表的有关操作

 最近在回顾线性存储结构-链式存储有关的操作,到现在基本上复习完毕,整理相关代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <strings.h>

struct node{
	int data;
	struct node* next;
}Node;

typedef struct node* LinkList;

LinkList CreatEmptylist() //创建空表
{
	LinkList p;
	p = (LinkList)malloc(sizeof(struct node));
	
	if(p == NULL)
	{
		perror("creat error!");
	}
	
	p->next = NULL;
	return p;
}

LinkList CreatList_head(LinkList L)//头插创建
{
	LinkList pnew;
	
	int i = 0;
	
	for(i = 0; i < 5; i++)
	{
		pnew = (LinkList)malloc(sizeof(struct node));
		
		scanf("%d",&pnew->data);
		
		pnew->next = L->next; 
		L->next = pnew;
	}
	return L;
}

LinkList CreatList_tail(LinkList L)//尾插创建
{
	LinkList pnew;
	LinkList rump;
	int i;	
	
	rump = L;
	
	for(i = 0; i < 5; i++)
	{
		pnew = (LinkList)malloc(sizeof(struct node));
		
		scanf("%d",&pnew->data);
	
		pnew->next = NULL;//将新节点的下一个结点置空
		rump->next = pnew;//尾结点与新节点相连
		rump = pnew;//rump指向尾部
	
//		rump->next = pnew; //rumo与新结点pnew相连接
//		rump = pnew;// rump始终指向尾部
	}
	
//	rump->next = NULL;//rump的下一个结点置空
	
	return L;
}

int ClearList(LinkList L) //清空链表
{
	LinkList p,q;
	
	p = L->next;
	
	while(p != NULL)
	{
		q = p->next;
		free(p);
		p = q;
	}
	
	L->next = NULL;
	printf("已经清空!");
}

int GetItem(LinkList L,int i)//查找
{
	int j = 1;
	LinkList p;
	
	p = L->next;
	
	while(p && j < i)
	{
		p = p->next;
		j++;
	}
	
	if(!p)
	{
		printf("Position error");
		return 0;
	}
	
	return p->data;
}

int ListRe(LinkList L,int i,int num) //修改
{
	int j = 1;
	LinkList p;
	
	p = L->next;
	
	while(p && j < i)
	{
		p = p->next;
		j++;
	}
	
	if(!p)
	{
		printf("Position error");
		return 0;
	}
	
	p->data = num;
}

int Linkinsert(LinkList L,int i,int num)//插入
{
	int j = 1;
	LinkList p,s;
	
	s = (LinkList)malloc(sizeof(struct node));
	
	p = L;
	
	while(p && j < i)
	{
		p = p->next;
		j++;
	}
	
	if(!p)
	{
		printf("insert error!");
		return 0;
	}
	
	s->data = num;
	
	s->next = p->next;
	p->next = s;
	
//	s->next = p;
//	s = p;
}

int ListDelete(LinkList L, int i)//删除
{
	int j = 1;
	LinkList p,q;
	
	if(L->next == NULL)
	{
		printf("List is Empty!");
		return 0;
	}
	
	p = L;
	while(p && j < i)
	{
		p = p->next;
		j++;
	}
	
	if(!p)
	{
		printf("Delete is Error!");
		return 0;
	}
	
	q = p->next;       	//用q来表示p的下一个结点
	p->next = q->next;  //绕过q,直接让p->next 指向 q的后继
	free(q);	//	释放掉q

//	q = p->next;
//	free(p);
//	p = q;
}

int PrintList(LinkList L)//打印链表
{
	LinkList pnew = L->next;
	while(pnew != NULL)
	{
		printf("%d ",pnew->data);
		pnew = pnew->next;
	}
	printf("\n");
}

int main()
{
	int n;
	int num;
	int newnum;
	
	LinkList phead1,phead2;
//	phead1 = CreatEmptylist();
	phead2 = CreatEmptylist();
	
//	printf("请输入5个数据\n");
//	phead1 = CreatList_head(phead1);
//	PrintList(phead1);
	
	printf("请再输入5个数据\n");
	
	phead2 = CreatList_tail(phead2);
	
	PrintList(phead2);
	
//	printf("请输入你在链表2中所需要获得的第n个数\n");
//	scanf("%d",&n);
//	Linkinsert(phead2,n,num);
//	ListDelete(phead2,n);
//	PrintList(phead2);
	
//	num = GetItem(phead2,n);
//	printf("%d\n",num);

	printf("请输入你需要修改第几个数\n");
	scanf("%d",&n);
	num = GetItem(phead2,n);
	printf("需要修改的数为%d\n",num);
	
	printf("请输入你需要将该数修改为多少\n");
	scanf("%d",&newnum);
	
	ListRe(phead2,n,newnum);
	PrintList(phead2);
	
	return 0;
}

在写关于尾插法的时候,发现写法有两种,当然严格意义上讲是同一种,第一种是pnew结点的next直接指向NULL,这样每次加入的pnew的后一位都是NULL,当pnew成为尾结点的时候已经完成了封尾,另一种就是在完成结点添加以后,r仍然指向尾结点的时候,r->next指向NULL,完成封尾。

以下是有关双向链表的操作:

#include <stdio.h>
#include <stdlib.h>
#include <strings.h>

struct node
{
	int data;
	struct node *pr;//前驱指针
	struct node *next;//后继指针
};

typedef struct node *CircleList;

CircleList CreatList()
{
	CircleList L;
	L = (CircleList)malloc(sizeof(struct node));
	
	if(L == NULL)
	{
		printf("creat list fail!\n");
		return 0;
	}
	
	L->pr = L;
	L->next = L;
	
	return L;
}

CircleList CircleList_insert(CircleList L)//头插
{
	CircleList pnew;
//	CircleList p;
	int i = 0;
	
//	p = L;
	
	for(i = 0; i < 5; i++)
	{
		pnew = (CircleList)malloc(sizeof(struct node));
		
		scanf("%d",&pnew->data);
		
		pnew->pr = L; //pnew的前驱指向L
		pnew->next = L->next;//pnew的后继指向 L->next
		L->next->pr = pnew;//L->next的前驱指向pnew
		L->next = pnew;//L的后继 指向 Pnew		
	}
	return L;
}

int CircleList_Delete(CircleList L,int num)//删除
{
	CircleList p ;
	int i = 1;
	
	p = L;
	
	while(i <= num)
	{
		p = p->next;
		i++;
	}
	
//	q = p;
	
	p->pr->next = p->next;
	p->next->pr = p->pr;
	free(p);
}

int PrintList(CircleList L)//打印链表
{
	CircleList pnew = L->next;
	
	while(pnew != L)
	{
		printf("%d ",pnew->data);
		pnew = pnew->next;
	}
	printf("\n");
}

int main()
{
	CircleList phead;
	
	phead = CreatList();
	phead = CircleList_insert(phead);	
	PrintList(phead);
	
	CircleList_Delete(phead,2);
	PrintList(phead);
	
	return 0;
	
}

猜你喜欢

转载自blog.csdn.net/qq_40949398/article/details/81388648
今日推荐