/*************************************************
* 单链表操作
*
**************************************************/
#include <stdio.h>
#include <stdlib.h>
#define OK 0
#define ERROR (-1)
typedef int Status;
typedef struct{
int type;
int content;
}ElemType;
typedef struct LNode{
ElemType data;
struct LNode *next;
}LNode,*LinkList;
Status GetElem_L(LinkList L,int i,ElemType *e)
{
//param
if((NULL==L)
||(NULL==e))
{
return ERROR;
}
//L为带头结点的单链表的头指针。
//当第i个元素存在时,其值赋给e并返回OK,否则返回ERROR
LinkList p;
int j;
p=L->next;j=0;//初始化,p指向第一个结点,j为计数器
while(p&&j<i){ //顺指针向后查找,直到p指向第i个元素或p为空
p=p->next;++j;
}
if(!p||j>i) return ERROR; //第i个元素不存在
*e=p->data; //取第i个元素
return OK;
}
Status ListInset_L(LinkList L,int i, ElemType e)
{
//param
if(NULL==L)
{
return ERROR;
}
//在带头结点的单链线性表L中第i个位置之前插入元素e
LinkList p=L->next; int j=0;
while(p&&j<i-1){p=p->next;++j;}//寻找第i-1个结点
if(!p||j>i-1) return ERROR; //i小于1或者大于表长加1
LinkList s=(LinkList)malloc(sizeof(LNode)); //生成新结点
s->data=e;s->next=p->next; //插入L中
p->next=s;
return OK;
}
Status ListDelete_L(LinkList L,int i, ElemType *e)
{
//param
if((NULL==L)
||(NULL==e))
{
return ERROR;
}
//在带头结点的单链线性表L中,删除第i个元素,并由e返回其值
LinkList p=L->next;int j=0;
while(p->next&&j<i-1){p=p->next;++j;}//寻找第i个结点,并令p指向其前驱
if(!(p->next)||j>i-1)return ERROR;//删除位置不合理
//p是要删除结点的前驱
LinkList q=p->next; p->next=q->next;//删除并释放结点
*e=q->data;free(q);
return OK;
}
void CreateList_L(LinkList L,int n)
{
//param
if(NULL==L)
{
return;
}
int type=1;
int content=12345;
//逆位序输入n个元素的值
L->next=NULL;//清空链表
int i;
for(i=n;i>0;--i){
LinkList p=(LinkList)malloc(sizeof(LNode));//生成新结点
p->data.type=type++;
p->data.content=content++;
//插入到表头
p->next=L->next;
L->next=p;
}
}
/*======================================
带头结点的单链表容易操作
========================================*/
int main(int argc,char *argv[])
{
LNode node;
LinkList header=&node;
//建立链表
printf("create list!\n");
CreateList_L(header,10);
int i;
ElemType e;
//遍历链表
i=0;
printf("print list:\n");
while(OK==GetElem_L(header,i++,&e))
{
printf("e.content=%d,e.type=%d\n",e.content,e.type);
}
printf("have %d number elements!\n",i);
//插入结点
printf("\ninsert 1,666 node @3\n");
e.content=666;e.type=1;
ListInset_L(header,3,e);
//遍历链表
i=0;
printf("print list:\n");
while(OK==GetElem_L(header,i++,&e))
{
printf("e.content=%d,e.type=%d\n",e.content,e.type);
}
printf("have %d number elements!\n",i);
//删除结点
printf("\ndelete node @8\n");
ListDelete_L(header,8,&e);
printf("e.content=%d,e.type=%d\n",e.content,e.type);
i=0;
printf("print list:\n");
while(OK==GetElem_L(header,i++,&e))
{
printf("e.content=%d,e.type=%d\n",e.content,e.type);
}
printf("have %d number elements!\n",i);
return 0;
}
1.头结点一定要,处理简单
2.typedef strcut sct{ 类型定义 sct要存在,不然编译报警告