链表优点: 按需申请空间,不用了就释放空间(更合理的使用了空间);头部中间插入删除数据,不需要挪动数据
不存空间浪费
链表缺点: 每一个数据,都要存一个指针去链接后面数据节点,不支持随机访问(用下标直接访问第i个)。
c语言实现:
SList.h
#ifndef _SLIST_H_
#define _SLIST_H_
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
/* 单链表的结构 */
typedef int SLTDataType;
typedef struct SListNode
{
SLTDataType data;
struct SListNode *next;
}SLTNode;
//打印链表
void SListPrint(SLTNode *phead);
//创建一个新节点
SLTNode *CreateSLTNode(SLTDataType x);
//尾插
void SListPushBack(SLTNode **pphead, SLTDataType x);
//头插
void SListPushFront(SLTNode **pphead, SLTDataType x);
//尾删
void SListPopBack(SLTNode **pphead);
//头删
void SListPopFront(SLTNode **pphead);
//查找x
SLTNode *SListFind(SLTNode *phead, SLTDataType x);
//在pos前插入x
void SListInsert(SLTNode **pphead, SLTNode *pos, SLTDataType x);
//在pos前后插入x
void SListInsertAfter(SLTNode *pos, SLTDataType x);
//清除pos前一个节点
void SListErase(SLTNode **pphead, SLTNode *pos);
//清除pos后一个节点
void SListEraseAfter(SLTNode *pos);
//释放链表
void SListDestory(SLTNode **pphead);
#endif
SList.c
#include "SList.h"
void SListPrint(SLTNode *phead)
{
SLTNode *cur = phead;
while( cur != NULL )
{
printf("%d->", cur->data);
cur = cur->next;
}
printf("NULL\n");
}
SLTNode *CreateSLTNode(SLTDataType x)
{
SLTNode *newnode = (SLTNode *)malloc(sizeof(SLTNode));
if(newnode == NULL)
{
printf("malloc failure.\n");
exit(-1);
}
newnode->data = x;
newnode->next = NULL;
return newnode;
}
void SListPushBack(SLTNode **pphead, SLTDataType x)
{
SLTNode *newnode = CreateSLTNode(x);
if(*pphead == NULL)
{
*pphead = newnode;
}
else
{
SLTNode *tail = *pphead;
while(tail->next != NULL)
{
tail = tail->next;
}
tail->next = newnode;
}
}
void SListPushFront(SLTNode **pphead, SLTDataType x)
{
SLTNode *newnode = CreateSLTNode(x);
newnode->next = *pphead;
*pphead = newnode;
}
void SListPopBack(SLTNode **pphead)
{
assert( *pphead != NULL );
if((*pphead)->next == NULL)
{
free(*pphead);
*pphead = NULL;
}
else
{
SLTNode *prev = NULL;
SLTNode *tail = *pphead;
while(tail->next)
{
prev = tail;
tail = tail->next;
}
free(tail);
prev->next = NULL;
}
}
void SListPopFront(SLTNode **pphead)
{
assert( *pphead != NULL);
SLTNode *next = (*pphead)->next;
free(*pphead);
*pphead = next;
}
SLTNode *SListFind(SLTNode *phead, SLTDataType x)
{
SLTNode *cur = phead;
while( cur->next )
{
if(cur->data == x)
{
return cur;
}
else
{
cur = cur->next;
}
}
return NULL;
}
void SListInsert(SLTNode **pphead, SLTNode *pos, SLTDataType x)
{
SLTNode *newnode = CreateSLTNode(x);
if(*pphead == pos)
{
newnode->next = *pphead;
*pphead = newnode;
}
else
{
SLTNode *posprev = *pphead;
while(posprev->next != pos)
{
posprev = posprev->next;
}
posprev->next = newnode;
newnode->next= pos;
}
}
void SListInsertAfter(SLTNode *pos, SLTDataType x)
{
SLTNode *newnode = CreateSLTNode(x);
newnode->next = pos->next;
pos->next = newnode;
}
void SListErase(SLTNode **pphead, SLTNode *pos)
{
if(*pphead == pos)
{
*pphead = pos->next;
free(pos);
}
else
{
SLTNode *prev = *pphead;
while(prev->next != pos)
{
prev = prev->next;
}
prev->next = pos->next;
free(pos);
}
}
void SListEraseAfter(SLTNode *pos)
{
SLTNode *next = pos->next;
pos->next = next->next;
free(next);
}
void SListDestory(SLTNode **pphead)
{
assert(pphead);
SLTNode *cur = *pphead;
while(cur != NULL)
{
SLTNode *next = cur->next;
free(cur);
cur = next;
}
*pphead = NULL;
}