链表是数据结构中的一部分,在这里我们不对链表的概念再做阐述,毕竟相关的资料和书籍有很多。我只想把有关链表的基本操作的代码放在博客中。在对链表的操作中,我们最常遇到的问题是对首结点和尾结点进行操作时与中间的结点有区别,所以造成代码的普遍性比较低差,只能解决特定问题,一旦需要操作的结点位于第一个和最后一个就束手无策。在这里,我们将解决这一问题。首先事先声明,笔者能力不足,哪里写的不好,还需要多多担待,在借鉴《C语言从入门到精通》相关内容的基础上绝对原创。
代码中的结点数据域中有两个变量,解决上述问题的关键就是让首结点和最后一个结点不存放我们需要的数据,至于存放什么?只要数据类型正确,你尽管输入就好,他不会影响相关操作的实现,哪怕是查找这样的操作,在代码中也已经忽略了第一个结点和最后一个结点。换句话说,他们是两个被废弃的结点,他们存在的意义只是为了相关操作的普遍性,里面的数据域毫无价值。
代码中的操作有:生成链表,打印链表,检查是否为空表,查找,插入和删除,这些都是用函数实现的,所以读者在使用代码的时候,需要自己在主函数中调用。生成链表这一操作的截止是输入的number为0时,即最后一个结点(无用的那个结点)的下一个节点输入的number为0(我们会用free将这段内存释放)。
#include <stdio.h>
#include <stdlib.h>
/*生成一个结点,数据域是姓名和号码*/
struct Student
{
char Name[20];
int Number;
struct Student *pNext;
};
/*定义一个全局变量来记录链表节点的数量*/
int iCount;
/*生成一个链表*/
struct Student *Creat()
{
iCount = 0;
struct Student *pHead;
struct Student *pEnd,*pNew;
pEnd = pNew = (struct Student*)malloc(sizeof(struct Student));
printf("please enter Student's name and number :\n");
scanf("%s",&pNew->Name);
scanf("%d",&pNew->Number);
while(pNew->Number != 0)/*当输入的号码是0时,停止生成链表*/
{
iCount++;
if(iCount == 1)
{
pNew->pNext = NULL;
pEnd = pNew;
pHead = pNew;
}
else
{
pNew->pNext = NULL;
pEnd->pNext = pNew;
pEnd = pNew;
}
pNew = (struct Student*)malloc(sizeof(struct Student));
/*第一个结点和最后一个结点是无效的,不让他们存有用的信息,这样对链表进行操作时,对第一个和最后一个结点的处理就是与其他结点没有差别的*/
scanf("%s",&pNew->Name);
scanf("%d",&pNew->Number);
}
iCount = iCount - 2;
free(pNew);
printf("\n");
return pHead;
}
/*打印链表*/
void Print(struct Student *Head)
{
struct Student *iHead;
iHead = Head->pNext;
while(iHead->pNext != NULL)
{
printf("%s",iHead->Name);
printf(" %d",iHead->Number);
printf("\n");
iHead = iHead->pNext;
}
printf("\n");
}
/*检查是否为空链表,即除了第一个结点和最后一个结点这两个无用结点外是否还有其他结点*/
void IsEmpty(struct Student *Head)
{
if(Head->pNext->pNext == NULL)
{
printf("this is a empty list");
}
else
{
printf("this is not a empty list");
}
}
/*根据号码查找这个节点并输出该节点*/
void Find(struct Student *Head,int j)
{
struct Student *pCurrent;
pCurrent = Head->pNext;
while(pCurrent->pNext->pNext != NULL)
{
while(pCurrent->Number != j)
{
pCurrent = pCurrent->pNext;
}
printf("%s",pCurrent->Name);
printf("%d",pCurrent->Number);
printf("\n");
pCurrent = pCurrent->pNext;
}
}
/*假定number是按从小到大排列的,现在要依据大小顺序把输入的信息插入到原先的链表中*/
void Insert(struct Student *Head)
{
struct Student *start;
start = Head;
struct Student *pNew;
printf("please enter what you want insert: \n");
pNew = (struct Student*)malloc(sizeof(struct Student));
scanf("%s",&pNew->Name);
scanf("%d",&pNew->Number);
while(start->pNext != NULL)
{
if(start->pNext->Number >= pNew->Number)
{
pNew->pNext = start->pNext;
start->pNext = pNew;
break;
}
start = start->pNext;
}
Head = Head->pNext;
while(Head->pNext != NULL)
{
printf("%s",Head->Name);
printf(" %d",Head->Number);
printf("\n");
Head = Head->pNext;
}
iCount++;
printf("\n");
}
void Delete(struct Student *pstart)
{
struct Student *start;
struct Student *current;
current = (struct Student*)malloc(sizeof(struct Student));
start = pstart;
printf("please enter what you want delete:\n");
scanf("%d",¤t->Number);
while(start->pNext->pNext != NULL)
{
if(start->pNext->Number == current->Number)
{
start->pNext = start->pNext->pNext;
free(start->pNext);
}
start = start->pNext;
}
pstart = pstart->pNext;
while(pstart->pNext != NULL)
{
printf("%s",pstart->Name);
printf(" %d",pstart->Number);
printf("\n");
pstart = pstart->pNext;
}
iCount--;
printf("\n");
}
int main()
{
struct Student *pHead;
pHead = Creat();
}