/*list.h
**对单链表的一些基本操作
*/
#include <stdio.h>
#include <malloc.h>
typedef int ElemType;
/*单链表的存储结构*/
typedef struct node{
ElemType data; /*数据域*/
struct node *next; /*指针域*/
}LNode,*LinkList;
/*输出链表(有头结点)的内容
**返回值:-1:链表为空
** 0 :成功
*/
int printLink(LinkList list)
{
int nodenum=1; //节点序号
LinkList p=list->next; //p指向第一个节点
//当无头结点时使用LinkList p=list;
if(!p)
return -1;
while(p)
{
printf("[%d]:%d/x20 ",nodenum,p->data); //每个节点数据之间用空格隔开
p=p->next;
++nodenum;
}
return 0;
}
//每次向表头添加一个元素的方式:逆序输入num个元素,创建具有num个元素的单链表(有头结点)
LinkList CreatList(int num)
{
int i;
LinkList pNewNode,list; //p指向链表的头结点
/*创建带头结点的空链表*/
list=(LinkList)malloc(sizeof(LNode));
list->next=NULL;
for(i=num;i>0;--i)
{
pNewNode=(LinkList)malloc(sizeof(LNode));
scanf("%d",&pNewNode->data);
//插入结点到表头
pNewNode->next=list->next;
list->next=pNewNode;
}
return list;
}
/*每次向表尾添加一个元素的方式:顺序输入n个元素,创建具有n个元素的单链表(有头结点)*/
LinkList CreatLinkList(int n){
LinkList p,r,list;
list=(LinkList)malloc(sizeof(LNode));
list->next=NULL;
ElemType e;
int i;
for(i=1;i<=n;i++){
scanf("%d",&e);
p=(LinkList)malloc(sizeof(LNode));
p->data=e;
p->next=NULL;
if(!list->next)
list->next=p;
else
r->next=p;
r=p;
}
return list;
}
/*在带头结点的链表的第i个节点之前插入一个节点。
**Return:-1:插入错误:插入位置小于1或大于链表长度。
** 0:插入成功。
*/
int InsertList(LinkList list,int i,ElemType e)
{
LinkList p=list; //p指向链表的头结点
int j=1;
while(p&&j<i) //当找到地i-1个节点或到达表尾
{
p=p->next;
j++;
}
if(!p||i<1) //i大于表长或i<1
return -1;
LinkList s=(LinkList)malloc(sizeof(LNode));
s->data=e;
s->next=p->next;
p->next=s;
return 0;
}
int GetLinkElem(LinkList L,int i,ElemType *e)
{ /* L为带头结点的单链表的头指针。当第i个元素存在时,其值赋给e并返回OK,否则返回ERROR */
int j=1; /* j为计数器 */
LinkList p=L->next; /* p指向第一个结点 */
while(p&&j<i) /* 顺指针向后查找,直到p指向第i个元素或p为空 */
{
p=p->next;
j++;
}
if(!p||i<1) /* 第i个元素不存在 */
return -1;
*e=p->data; /* 取第i个元素 */
return 0;
}
/*
**Gets the last element in a Linklist
**Return:(1)list不为空链表时,返回the last element in a Linklist
** (2)list为空链表时,返回头结点
*/
LinkList LastNode(LinkList list)
{
LinkList p=list->next;
if(p)
{
while(p->next)
p=p->next;
}
else
return list;
return p;
}
/*在表尾添加一个元素*/
void AppendList(LinkList list,ElemType e)
{
LinkList newNode,lastNode;
newNode=(LinkList)malloc(sizeof(LNode));
newNode->data=e;
newNode->next=NULL;
lastNode=LastNode(list);
lastNode->next=newNode;
}
/*
*/
int DeleteList(LinkList list,int i,ElemType *e)
{
int j=0;
LinkList q;
LinkList p=list;
while(p&&j<i-1) //寻找第i-1个节点
{
p=p->next;
j++;
}
if(!p||i<1)
return -1;
q=p->next;
p->next=q->next;
*e=q->data;
free(q);
return 0;
}
/*将单链表置为空表*/
void ClearLinkList(LinkList list){
LinkList p,q;
p=list->next; //list指向头结点,p指向第一个节点
//释放链表中各个节点
while(p){
q=p->next;
free(p);
p=q;
}
list->next=NULL;
}
/*list.c
**用于测试list.h中单链表的各种操作
*/
#include "list.h"
int main()
{
int nodenum;
LinkList newList;
//创建链表操作
printf("请输入要创建的链表的节点数/n");
scanf("%d",&nodenum);
printf("请顺序输入各节点的内容/n");
newList=CreatLinkList(nodenum);
printf("你创建的链表如下:/n");
if(printLink(newList)==-1)
printf("该链表为空链表");
//插入操作
int insertLocation,insertValue;
printf("/n请分别输入你要插入元素的位置和值/n");
scanf("%d",&insertLocation);
scanf("%d",&insertValue);
if(InsertList(newList,insertLocation,insertValue))
printf("插入错误:插入位置小于1或大于链表长度/n");
if(printLink(newList)==-1)
printf("该链表为空链表/n");
//在尾部添加操作
int appendValue;
printf("/n请输入你要添加到表尾元素的值/n");
scanf("%d",&appendValue);
AppendList(newList,appendValue);
printLink(newList);
//获取第i个元素的值
int getLocation,getValue;
printf("/n请输入要获取节点数据在链表中的位置/n");
scanf("%d",&getLocation);
GetLinkElem(newList,getLocation,&getValue);
printf("第%d个节点的值为%d",getLocation,getValue);
//删除操作
printf("/n选择要删除元素的序号/n");
int delnum;
ElemType data;
scanf("%d",&delnum);
DeleteList(newList,delnum,&data);
printf("删除的元素为:%d/n",data);
if(printLink(newList)==-1)
printf("该链表为空链表");
}