//-----------------------------普通链表-------------------------------//
#include<stdio.h>
#include<stdlib.h>
typedef int ElemType;
typedef struct LNode
{
ElemType data;
struct LNode *next;
}LNode,*LinkList;
//链表函数最重要的就是要返回头结点的指针。
//有两种方式,一种是直接返回用return语句返回头结点,另一种是传指针进去!
//LinkList是一个指针型的结构体,LinkList里面存的是一个结构体的基地址,用指针型的可以在函数调用的时候返回改变的值。
//这个函数里面LinkList *L这个定义,不是说将L纯粹的定义成LinkList,纯粹的定义成LinkList 是(LinkList L),
//这里的意思是说将L这个指针的地址带入运算,不是L里面存的那个地址,即函数里面那个*L相当于是 *(&L),这个叫做指针的指针。
void InitList(LinkList *L,int n)
{
LinkList p;
int i;
*L = (LinkList)malloc(sizeof(LNode)); //头节点并未储存数据(*L)->next = NULL; //先建立一个带头节点的单链表
for(i = n;i > 0;--i)//表头插入,逆序先进后出!!
{
p = (LinkList)malloc(sizeof(LNode));
scanf("%d",&p->data);
p->next = (*L)->next;
(*L)->next = p;
}/*
//表尾插入,顺序 如想要先进先出,则需设置两个指针
LinkList head,tail,p;
int i;
head = tail = (LinkList)malloc(sizeof(LNode));
Head = tail = *L;
Head->next = tail->next = NULL; // Head头指针,tail为尾指针
for(i = n; i > 0; --i)
{
p = (LinkList)malloc(sizeof(LNode));
scanf("%d",&p->data);
tail->next = p;
tail = p
}
tail->next = NULL;
*/
}/*
void InitList(LinkList *L) //建立只带头结点的链表
{*L = (LinkList)malloc(sizeof(LNode));
if(!(*L))
{ exit(0);
}
(*L)->next = NULL;
}*/
void ListInsert(LinkList *L,int i,ElemType e) //在单链表L中第i个位置之前插入元素e
{
LinkList p,s;
int j = 0;
p = *L;
while(p && j < i-1) //寻找第i-1个节点
{
p = p->next;
++j;
}
if(!p || j > i-1)
{
exit(0);
}
s = (LinkList)malloc(sizeof(LNode));
s->data = e;
s->next = p->next; //先插入后连接
p->next = s;
}/*
void FirstInsert(LinkList *L,ElemType e) //头插发
{
LinkList s ;
s = (LinkList)malloc(sizeof(LNode));
s->data = e;
s->next = (*L)->next; //头结点没有储存数据,所以继续做头结点的好
(*L)->next = s; }
*/
/*
void LastInsert(LinkList *L,ElemType e) //尾插法
{
LinkList p,s;
p = *L;
while(p && p->next != NULL) //找尾结点
{
p = p->next;
}
s = (LinkList)malloc(LNode);
s->data = e;
p->next = s;
s->next = NULL;
}
*/ElemType ListDelete(LinkList *L,int i,ElemType *e) //删除第i个元素,并用e返回其值
{
LinkList p,q ;
int j = 0;
p = *L;
while((p->next)&&(j < (i-1)))
{
p = p->next;
++j;
}//此处必须为p->next,因为当p为L时,L->data 无数据
if(!(p->next) || j > i-1) //注意此处为p->next,即是第i个元素的位置
{
exit(0);
}
q = p->next;
p->next = q->next;
*e = q->data;
free(q);
return *e;
}
void PrintList(LinkList L)
{
LinkList p;
p = L->next;
while(p)
{
printf("%d",p->data);
p = p->next;
}
}
ElemType GetElem(LinkList L, int i, ElemType *e) //得到第i个元素,并返回
{
LinkList p,q;
int j = 0;
p = L; //注意p的大小写,很难分辨;
while(p->next && j < i-1)
{
p = p->next;
++j;
}
if(!(p->next) || j > i-1)
{
exit(0);
}
q = p->next;
*e = q->data;
return *e;
/*
LinkList p;
int j = 1;
p = L->next;
while( p && j < i )
{
p = p->next;
++j; }
if(!p && j > i) {
exit(0); }
*e = p->data;
return *e;
*/
}
int LocateElem(LinkList L,ElemType e) //指出该元素为链表中的第几个元素
{
LinkList p;
int i = 1;
p = L->next;
while(p && (p->data != e))
{
p = p->next;
++i;
}
if(!p)
{
return 0;
}
return i;
}
int MuchElemType(LinkList L) //返回元素个数,而不是结点个数,头结点无数据
{
LinkList p;
int j = 0;
p = L;
while(p->next)
{
p = p->next;
++j;
}
return j;
}
void DestroyList(LinkList L) //销毁链表
{
LinkList p ;
while(L)
{
p = L;
L = L->next;
free(p);
}
L = NULL;
}
int main()
{
LinkList *L;
ElemType *e;
int n = 5;
e = NULL; //必须先定义,然后才能赋值
L = NULL;
e = (ElemType *)malloc(sizeof(ElemType));
L = (LinkList *)malloc(sizeof(LNode *)); //very important!
InitList(L,n);
// FirstInsert(L,8);
ListInsert(L,1,2);
printf("%d\n",ListDelete(L,3,e));
printf("%d\n",GetElem(*L,4,e));printf("%d\n",LocateElem(*L,2));
printf("%d\n",MuchElemType(*L));
PrintList(*L);
return 0;
}