/* 单链表:
优点:
1,解决了线性顺序表的长度固定的问题
2,删除、插入元素的时间复杂度为 O(1),
缺点:
读取元素时间复杂度为O(n)
*/
typedef int ElemType;
typedef int Status;
#define ERROR 0
#define OK 1
#define HEAD 0
struct Node
{
ElemType data;
struct Node *Next;
};
typedef Node* LinkList;
/************************************************************************/
/* 创建一个有N个元素的单链表 */
/************************************************************************/
Status CreateLinkList(int N,LinkList *L)
{
/*万物的开始,神说要有光,于是便有了光
单链表说要有结点,于是便有了结点*/
*L=new Node;
(*L)->data=0;
/*头结点,尾结点都是我*/
(*L)->Next=NULL;
#if HEAD
/*头插法*/
LinkList p;
for (int i=0;i<N;i++)
{
/*你要插入点东西吧*/
p=new Node;
p->data=(i+1)*N;
p->Next=NULL;/*注意了,这里一定要加NULL,不然到时候清空列表的时候p->Next不知道是什么了*/
/*算法关键在这里了,把新结点插到头结点和后面的结点之间。
所以就把头结点的后继,变成新结点的后继了。
此时头结点没后继了,不能断了香火呀,好吧,把新节点挂在头结点的后面,这样皆大欢喜*/
p->Next=(*L)->Next;
(*L)->Next=p;
}
#else
/*尾插法*/
/*一个是要插入的结点,一个是尾结点*/
LinkList p,r;
/*尾巴*/
r=(*L);
for (int i=0;i<N;i++)
{
/*新结点*/
p=new Node;
p->data=(i+1)*N;
p->Next=NULL;/*注意了,这里一定要加NULL,不然到时候清空列表的时候p->Next不知道是什么了*/
/*把新结点挂在当前链表的尾巴上*/
r->Next=p;
/*长了根新尾巴*/
r=p;
}
#endif
return OK;
}
/************************************************************************/
/* 获取第N个元素 */
/************************************************************************/
Status GetElem(int N,LinkList L,ElemType *e)
{
if (L==NULL)
return ERROR;
LinkList p=L;
/*时间复杂度O(N)*/
int j=1;
while(j<N &&p)
{
p=p->Next;
++j;
}
/*如果没找到point*/
if (!p ||j>N)
return ERROR;
(*e)=p->data;
return OK;
}
/************************************************************************/
/* 插入第N个元素 */
/************************************************************************/
Status InsertElem(int N,LinkList *L,ElemType e)
{
if (L==NULL)
return ERROR;
LinkList p=(*L),q;
/*下面这里是查找插入的位置的前一个结点。。。跟前面获取元素代码相同。
这个时间复杂度应该不要算在插入头上吧,如果要算的话,时间复杂度瞬间提升为O(n)。。。*/
int j=1;
while (j<N-1 &&p)
{
p=p->Next;
++j;
}
/*如果没找到point*/
if (!p ||j>N-1)
return ERROR;
q=new Node;
q->data=e;
q->Next=p->Next;
p->Next=q;
return OK;
}
/************************************************************************/
/* 删除第N个元素 */
/************************************************************************/
Status DeleteElem(int N,LinkList *L,ElemType *e)
{
if (L==NULL)
return ERROR;
LinkList p=(*L),q;
/*查找要删除的结点前驱位置*/
int j=1;
while (j<N-1 &&p)
{
p=p->Next;
++j;
}
/*如果没找到point*/
if (!p ||j>N-1)
return ERROR;
q=p->Next;
p->Next=q->Next;
delete(q);
return OK;
}
/************************************************************************/
/* 删除整个表 */
/************************************************************************/
Status ClearLinkList(LinkList *L)
{
if (L==NULL)
return ERROR;
LinkList p=(*L),q;
while(1)
{
q=p->Next;
p->Next=q->Next;
delete(q);
if (p->Next==NULL)
{
delete(p);
break;
}
}
return OK;
}