本文学习总结最常用两种结构:
定义无头单向非循环链表节点:
typedef struct SListNode
{
ElemType data;
struct SListNode *next;
}SListNode;
定义无头单向非循环链表结构:
typedef struct SList
{
SListNode *head; //结构体内为一个单链表节点类型的指针
}SList;
void SListInit(SList *plist);
void SListPushBack(SList *plist,ElemType x);
static SListNode* _Buynode(ElemType x); //申请节点
void SListShow(SList *plist);
void SListPushFront(SList *plist, ElemType x);
void SListPopBack(SList *plist);
void SListDestroy(SList *plist);
void SListPopFront(SList *plist);
size_t SListLength(SList *plist);
void SListClear(SList *plist);
SListNode *SeqListFind(SList *plist,ElemType key);
void SListDeleteByVal(SList *plist, ElemType key);
void SListReverse(SList *plist);
void SListInsertByVal(SList *plist, ElemType x);
void SListSort(SList *plist);
初始化链表:
void SListInit(SList *plist)
{
plist->head = NULL;
}
结点的空间申请:
static SListNode* _Buynode(ElemType x)
{
SListNode *s = (SListNode*)malloc(sizeof(SListNode));
assert(s!=NULL);
s->data = x;
s->next = NULL;
return s;
}
链表尾插:
void SListPushBack(SList *plist, ElemType x)
{
assert(plist!=NULL);//断言
SListNode *s = _Buynode(x);//结点申请
//如果插入的结点为第一个结点
if (plist->head==NULL)
{
plist->head = s;
}
SListNode *p = plist->head;
while (plist->head != NULL)
p = p->next;
p->next = s;
}
显示链表:
void SListShow(SList *plist)
{
SListNode *p = plist->head;
while (p!=NULL)
{
printf("%d-->",p->data);
p = p->next;
}
printf("Over.\n");
}
单链表头部插入:
void SListPushFront(SList *plist, ElemType x)
{
assert(plist!=NULL);
SListNode *s = _Buynode(x);
s->next = plist->head;
plist->head = s;
}
单链表尾部删除:
void SListPopBack(SList *plist)
{
assert(plist!=NULL);//断言
SListNode *p;
if (plist->head == NULL)//链表为空时;
return;
p = plist->head;
//当链表只有一个结点时
if (p->next == NULL)
{
free(p);
plist->head = NULL;
return;
}
//至少两个结点时
while (p->next->next != NULL)
p = p->next;
free(p->next);
p->next = NULL;
}
单链表的清除:
void SListClear(SList *plist)
{
assert(plist != NULL);
SListNode *p = plist->head;
while (p != NULL)
{
plist->head = p->next;
free(p);
p = plist->head;
}
}
单链表的摧毁:
void SListDestroy(SList *plist)
{
SListClear(plist);
plist->head = NULL;
}
单链表头部删除:
void SListPopFront(SList *plist)
{
assert(plist!=NULL);
SListNode *p = plist->head;
if (plist->head == NULL)
return;
plist->head = p->next;
free(p);
}
单链表长度:
size_t SListLength(SList *plist)
{
assert(plist!=NULL);
size_t len = 0;
SListNode *p = plist->head;
while (p != NULL)
{
len++;
p = p->next;
}
return len;
}
单链表按值查找:
SListNode *SeqListFind(SList *plist, ElemType key)
{
assert(plist != NULL);
SListNode *p = plist->head;
while (p != NULL && p->data != key)
p = p->next;
return p;
}
单链表按值删除:
void SListDeleteByVal(SList *plist, ElemType key)
{
assert(plist!=NULL);
SListNode *prev = NULL;
SListNode *p = SeqListFind(plist,key);
if (p == NULL)
{
printf("要删除的结点不存在.\n");
return;
}
//判断是否找到的是第一个结点(特殊处理)
if (p == plist->head)
plist->head = p->next;
else
{
prev = plist->head;
while (prev->next != p)
prev = prev->next;
//删除结点
prev->next = p->next;
}
free(p);
}
单链表转置操作:
void SListReverse(SList *plist)
{
assert(plist != NULL);
SListNode *p = plist->head->next;
SListNode *q;
if (p->next == NULL)
return;
//断开第一个结点
plist->head->next = NULL;
while (p != NULL)
{
q = p->next;
p->next = plist->head;
plist->head = p;
}
}
单链表按值插入:
void SListInsertByVal(SList *plist, ElemType x)
{
assert(plist!=NULL);
SListNode *prev = NULL;
SListNode *p = plist->head;
SListNode *s = _Buynode(x);
//判断要插入的位置
while (p!=NULL && x>p->data)
{
prev = p;
p = p->next;
}
if (prev == NULL)//需进行头插
{
s->next = p;
plist->head = s;
}
else
{
s->next = prev->next;
prev->next = s;
}
}
单链表排序:
void SListSort(SList *plist)
{
assert(plist != NULL);
SListNode *p = plist->head->next;
SListNode *q, *t, *prev = NULL;
plist->head->next = NULL;//断开链表
t = plist->head;
while (p != NULL)
{
q = p->next;
//把p结点摘除进行按值插入,升序
while (t!=NULL && p->data>t->data)
{
prev = t;
t = t->next;
}
if (prev==NULL)
{
prev->next = plist->head;
plist->head = p;
}
else
{
p->next = prev->next;
prev->next = p;
}
p = q;
t = plist->head;
}
}
下一次将对带头双向循环链表的基本操作进行叙述。