顺序表的单链表存储:
1 单链表的建立,建立单链表有头插法和尾插法两种,前者的链表元素与初始化顺序相反,后者则相同,可根据需要选择,下面的程序采用的是尾部插入建立,是为了方便测试逆置和中间结点的查找。
2 单链表的删除和插入: 首先,删除结点,一般会找到一个结点,比如是p,然后是删除后面结点还是前面结点,如果是删除后面的结点,则直接删除后替换就 可以了;如果是删除前面结点,由于单链表的性质,所以可以将p中结点内容复制到要删除的结点数据域中,然后就与后删一样了。插入也分为前插与后插,后插比较简单,前插也可改为后插,此时将两个结点的数据互换即可。
3 单链表的逆置和中间结点的查找,写了个代码测试了下,linux下gcc测试可用。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef int ElemType;
typedef struct _LinkNode{
ElemType data;
struct _LinkNode *next;
}LinkNode;
//创建带头结点的单链表,尾插法建立
LinkNode* CreateLinkList(LinkNode *L)
{
ElemType data;
LinkNode *r = NULL, *p = NULL;
L = (LinkNode*)malloc(sizeof(LinkNode));
if(NULL == L)
return NULL;
memset(L, 0 , sizeof(LinkNode));
r = L;
scanf("%d",&data);
while(data != 0){
p = (LinkNode*)malloc(sizeof(LinkNode));
//malloc出错处理
p->data = data;
p->next = NULL;
r->next = p;
r = p;
scanf("%d",&data);
}
return L;
}
//打印带头结点的单链表中的所有value
void PrintLink(LinkNode *L)
{
LinkNode *p = L->next;
while(p != NULL){
printf("%d ", p->data);
p = p->next;
}
printf("\n");
return ;
}
//带头结点的单链表逆置
void LinkReverse(LinkNode *L)
{
if(L->next == NULL)
return;
LinkNode *p = NULL, *q = NULL;
p = L->next;
q = p->next;
while(q){
p->next = q->next;
q->next = L->next;
L->next = q;
q = p->next;
}
return ;
}
//使用大小指针查找未知长度单链表的中间结点,L为头结点
//奇数个结点返回中间结点,偶数个则返回靠前一个的结点
LinkNode* LinkSearchMid(LinkNode *L)
{
if(L->next == NULL)
return NULL;
LinkNode *p, *q;
p = L->next;
q = L->next;
while(p->next != NULL){
p = p->next->next;
if(!p){
break;
}
q = q->next;
}
return q;
}
int main()
{
LinkNode *L = NULL;
L = CreateLinkList(L);
PrintLink(L);
LinkNode *p = NULL;
p = LinkSearchMid(L);
if(p)
printf("mid = %d\n",p->data);
else
printf("Link is empty!\n");
LinkReverse(L);
PrintLink(L);
return 0;
}