C编写循环链表,并删除其中的元素

先放大招
#include <stdio.h>
#include <Windows.h>

//创建一个结构体
typedef struct Node
{
	int				data;	// 数据 
	struct Node		*pNext;	// 指针
}NODE, *PNODE;

// 函数功能:创造一个循环链表
// 函数参数:无
// 函数返回:返回链表首地址
PNODE creatList()
{
	int		length,i,val;			// 创建有效结点的长度,以及用来存放用户输入结点的值
	NODE	*pNew, *pTail, *pHead;  
	
	// 创建一个不存放有效数据的头结点
	pHead = (NODE*)malloc(sizeof(NODE));
	memset(pHead, 0, sizeof(NODE));

    // 开始只有一个结点,自身就指向自身。
	pTail = pHead;
	pTail->pNext = pHead->pNext;

 	printf("请输入想要创建链表结点的个数:len=");
	scanf("%d",&length);

	// 使用for循环来控制创建结点的个数
    for (i = 0;i< length;i ++)
    {
		// 为第i+1个结点进行赋值
		printf("请输入第%d个节点的值:",i+1);
		scanf("%d",&val);
		
		// 开辟一个新的指针,这个指针指向了第i+1个结点
		pNew = (PNODE)malloc(sizeof(NODE));
		memset(pNew, 0, sizeof(NODE));

		// 使新指针的数据为刚刚输入的数据
		pNew ->data = val;

		// 让新的结点与上一个结点联系起来
		pTail ->pNext =pNew;
		
		// 使这个新指针指向了第一个结点
		pNew ->pNext = pHead->pNext;
		
		// 刷新pTail,指向最新的结点
		pTail = pNew;
    }
	// 返回头结点的地址
  return pHead;
}

// 函数功能:遍历整个循环链表
// 函数参数:头指针
// 函数返回:无
void traverseLinkList(PNODE pHead)
{
	NODE	*p; 

	
	// 指针p指向第一个结点
	p = pHead->pNext;
	if (p == NULL)
		return;

	// 输出指向该结点的数据,并且是指针指向下一个结点
	printf("%d\n",p->data);
	p =	p->pNext;
	
	// 只输出一遍即可
	while(p != pHead->pNext)
	{
		printf("%d\n",p->data);
		p = p->pNext;
	}
	printf("\n");
	return;   
}

// 函数功能:删除指定位置的结点
// 函数参数:头指针,第几个结点  
// 函数返回:删除结点之后的指针
NODE *deleteElement(NODE *pHead,int pos)
{
	// 定义两个指针
	NODE	*p, *q;
	int		i ;

	p = pHead;
	i=0;

	// 找到要删除的结点
	while ( NULL != p->pNext && i< pos-1 )
	{
		p = p->pNext;
		i++;
	}
    
	q = p->pNext;

	// 将要删除的结点内容清空
	// 只有一个节点的情况
	if (p == p->pNext)
	{
		p->data = 0;
		p->pNext = NULL;
		return p;

	}
	// 剩下的情况
	// 令前一个指针指向要删除结点的下一个结点
	else
	{
		p->pNext = q->pNext;
		free(q);
		// 将其指针指向空
		q = NULL;
		return p;
	} 
}


void main()
{
	PNODE pHead = NULL;
	pHead = creatList();
	pHead = deleteElement(pHead,5);
	traverseLinkList(pHead);
}
       做这个程序碰到了一些问题,其中链表头只是做了一个标志,里面没有放东西,真正的放数据的是从第二个链表结点开始,所以循环的话只需把第二个结点看成第一个就可,最后一个结点也指向第二个节点,当然,删除中间的没问题,但是当我们删除第二个结点时候,那么头结点我们就不要了?因为头结点与链表的联系就是靠着第二个节点,第二个节点没了,那头结点就只剩下一个头结点了,这样我们就得单独讨论出来。我想了想,那我就把头结点给单独出来,等链表删除完之后,再和已经处理好的进行链接,这样我们就可以看到是从哪里断开的了。
posted @ 2014-10-10 09:39  赫凯  阅读(45)  评论(0)    收藏  举报