/**********************************************
功能:单向链表操作(注意Head指针
需要被改变时传入的是二级指针)
日期:2009.12.29
作者:DC
***********************************************/
#include <stdio.h>
#include <stdlib.h>
#define OVER_FLOW -2
#define OK 0
typedef int ElemType;
typedef struct node
{
ElemType data;
struct node *next;
} Node, *LinkList;
/*构造一个空表(其实就是一个头指针指向NULL)*/
void Init_LinkList(LinkList *Head_pointer)
{
*Head_pointer = NULL;
}
/*插入一个元素(头插)*/
int Insert_First(LinkList *Head_pointer, ElemType x)
{ /*第一步:分配一个节点并赋值*/
LinkList p;
p = (LinkList) malloc(sizeof(Node));
if (p == NULL)
return OVER_FLOW;
p->data = x;
/*第二步:调整新节点的指针
和插入点前的元素的指针(即头指针)*/
p->next = *Head_pointer;
*Head_pointer = p;
return OK;
}
/*查找一个链表,由于不需要改变头指针指向,所以直接传递头指针即可*/
LinkList Location_LinkList(LinkList Head, ElemType x)
{
LinkList p;
p = Head;
while(p != NULL)
{
if (p->data == x)
break;
p = p->next;
}
}
/*删除一个元素*/
int Delete_LinkList(LinkList *Head_pointer, ElemType x)
{
/*第一步:定义好临时指针*/
LinkList p, q;
p = *Head_pointer;
/*第二步:如果删除的节点是头结点*/
if (p->data == x)
{
*Head_pointer = (*Head_pointer)->next;
free(p);
return OK;
}
/*第三步:如果删除的节点非头结点*/
else
{
q=p; p=p->next;
while(p != NULL)
{
if (p->data == x)
{
q->next = p->next; /*对于尾节点,这里是NULL*/
free(p);
return OK;
}
q=p; p=p->next;
}
}
return OK;
}
/*遍历链表*/
void Show_LinkList(LinkList Head)
{
LinkList p;
printf("\n");
p = Head; /*所有的链表操作都要从头结点开始*/
if (p == NULL)
printf("空表\n");
while(p != NULL)
{
printf(" %d", p->data);
p = p->next;
}
}
/*清空链表*/
void SetNull_LinkList(LinkList *Head_pointer)
{
LinkList p, q;
p = *Head_pointer;
while(p != NULL)
{
q = p;
p = p->next;
free(q);
}
Head_pointer = NULL;
}
/*计算链表长度*/
int Length_LinkList(LinkList Head)
{
LinkList p;
int sum = 0;
p = Head;
while(p != NULL)
{
sum++;
p = p->next;
}
return sum;
}
int main(int argc, char *argv[])
{
LinkList Head;
int i;
Node *loca;
ElemType x;
Init_LinkList(&Head);
do
{
printf("\n");
printf("1--------插入一个元素(Insert)\n");
printf("2--------查询一个元素(Locate)\n");
printf("3--------删除一个元素(Delete)\n");
printf("4--------显示所有元素(Showall)\n");
printf("5--------计算表的长度(Length)\n");
printf("6--------退出(Exit)\n");
printf("请输入:");
scanf("%d", &i);
switch(i)
{
case 1: printf("请输入要插入的数据:");
scanf("%d", &x);
if (Insert_First(&Head, x) != OK)
printf("插入数据失败!\n");
else
printf("插入数据成功!\n");
break;
case 2: printf("请输入要查询的分数:");
scanf("%d", &x);
loca = Location_LinkList(Head, x);
if(loca != NULL)
printf("查找成功(Found)!\n");
else
printf("查找失败(Not found)!\n");
break;
case 3: printf("请输入要删除的分数:");
scanf("%d", &x);
if(Delete_LinkList(&Head, x) != OK)
printf("删除失败!\n");
else
printf("删除成功!\n");
break;
case 4: printf("遍历显示表中数据:\n");
Show_LinkList(Head);
break;
case 5: printf("表的长度是:%d", Length_LinkList(Head));
break;
case 6: break;
default:printf("错误选择,请重新选择:");
break;
}
}while(i != 6);
SetNull_LinkList(&Head);
printf("链表已清空!(Clear OK!)\n");
return 0;
}