今天我又来发博客啦,刚刚学了链表,现在把一些学的知识总结成博文发出去,希望能对小伙伴们有帮助,也希望各位大佬指出我的错误,码字不易,感谢大家QAQ
链表介绍
链表是一系列的存储数据元素的单元通过指针串接起来形成的,因此每个单元至少有两个域,一个域用于数据元素的存储,另一个或两个域是指向其他单元的指针。这里具有一个数据域和多个指针域的存储单元通常称为节点(node)。 链表的第一个节点和最后一个节点,分别称为链表的头节点和尾节点。尾节点的特征是其 next 引用为空(null)。链表中每个节点的 next 引用都相当于一个指针,指向另一个节点,借助这些 next 引用,我们可以从链表的头节点移动到尾节点。
说这么多,我好久也不懂,所以
上图!
基本功能
存储结构
typedef int ElemType;
typedef struct Node{//这里的struct node 为结构体类型名,可以用来给变量赋类型
ElemType data;
struct Node *next;
}Node,*LinkList;//LinkList 与 Node* 作用一样,这里的Node 和LinkList都可为变量赋类型
头插法
void CreatFromHead(LinkList head)//这里往函数传头指针,用Node *head一样,都是传地址
{ //头插法
Node *s;
char c;
int flag=1;
while(flag)
{
c=getchar();
if(c!='$')
{
s=(Node*)malloc(sizeof(Node));
s->data=c;
s->next=head->next;
head->next=s;
}
else {flag=0;
}
}
}
注意 此处要在主函数建立头节点,并把头节点后指向空
头插法是逆序
输入$为止
上图!
还有,这是开始不把头节点指向空的结果
尾插法
void CreatFromTail(Node *head)
{
Node *p; //尾插法
int flag=1;
p=head;
char c,d;
while(flag)
{
c=getchar();
d=getchar();//要将输入时的空格除去
if(c!='$')
{
p->next = (Node*)malloc(sizeof(Node));
p->next->data=c;
p = p->next;
}
else
{
flag=0;
p->next=NULL;
}
}
}
尾插为正序
上图!
查找
Node *Get(LinkList head,int i)//查找第i个结点,返回结点
{
int j;
Node *p;
if(i<=0) return NULL;
p=head;
j=0;
while(p->next!=NULL&&(j<i))
{
p=p->next;
j++;
}
if(i=j) return p;
else return NULL;
}
返回链表长度
int ListLength(LinkList head)
{
Node *p;
p=head->next;
int j=0;
while(p!=NULL)
{
p=p->next;
j++;
}
return j;
}
输出链表
void OutputList(Node *head){//输出链表
Node *p = head->next;
while(p){
printf("%c ",p->data);
p = p->next;
}
}
在第i个结点后插入e
void InsList(LinkList head,int i,char e)//在第i个结点后插入e
{
Node *pre,*s;
int k;
if(i<=0) return;
pre=head;
k=0;
while(pre!=NULL&&k<i)
{
pre=pre->next;
k=k+1;
}
if(pre==NULL)
{
printf("WRONG PLACE");
return ;
}
s=(Node*)malloc(sizeof(Node));
s->data=e;
s->next=pre->next;
pre->next=s;
return;
}
删除第i个结点并用e返回其值
void DelList(LinkList head,int i,char *e)//删除第i个结点并用e返回其值
{
Node *pre,*r;
int k;
pre=head;
k=0;
while(pre->next!=NULL&&k<i-1)
{
pre=pre->next;
k=k+1;
}
if(pre->next==NULL)
{
printf("WRONG PLACE");
return;
}
r=pre->next;
*e=r->data;
pre->next=r->next;
free(r);
return;
}
销毁链表
void DestroyList(LinkList head)//销毁链表
{
Node *p;
while(head->next!=NULL)
{
p=head->next;
head->next=p->next;
free(p);
}
}
两个链表的有序合并
Node *Merge(Node *head_a, Node *head_b){
Node *a,*b;
Node *c,*head_new;
a=head_a->next;
b=head_b->next;
head_new=head_a;
head_new->next=NULL;
c=head_new;
while(a!=NULL&&b!=NULL)
{
if(a->data<=b->data)
{
c->next=a;
c=a;
a=a->next;
}
else{
c->next=b;
c=b;
b=b->next;
}
}
if(a)
{
c->next=a;
}
else c->next=b;
return(head_new);
}
主体代码
#include<stdio.h>
#include<stdlib.h>
typedef int ElemType;
typedef struct Node{//这里的struct node 为结构体类型名,可以用来给变量赋类型
ElemType data;
struct Node *next;
}Node,*LinkList;//LinkList 与 Node* 作用一样,这里的Node 和LinkList都可为变量赋类型
void CreatFromHead(LinkList head)//这里往函数传头指针,用Node *head一样,都是传地址
{ //头插法
Node *s;
char c;
int flag=1;
while(flag)
{
c=getchar();
if(c!='$')
{
s=(Node*)malloc(sizeof(Node));
s->data=c;
s->next=head->next;
head->next=s;
}
else {flag=0;
}
}
}
void CreatFromTail(Node *head)
{
Node *p; //尾插法
int flag=1;
p=head;
char c,d;
while(flag)
{
c=getchar();
d=getchar();//要将输入时的空格除去
if(c!='$')
{
p->next = (Node*)malloc(sizeof(Node));
p->next->data=c;
p = p->next;
}
else
{
flag=0;
p->next=NULL;
}
}
}
Node *Get(LinkList head,int i)//查找第i个结点,返回结点
{
int j;
Node *p;
if(i<=0) return NULL;
p=head;
j=0;
while(p->next!=NULL&&(j<i))
{
p=p->next;
j++;
}
if(i=j) return p;
else return NULL;
}
int ListLength(LinkList head)
{
Node *p;
p=head->next;
int j=0;
while(p!=NULL)
{
p=p->next;
j++;
}
return j;
}
void OutputList(Node *head){//输出链表
Node *p = head->next;
while(p){
printf("%c ",p->data);
p = p->next;
}
}
void InsList(LinkList head,int i,char e)//在第i个结点后插入e
{
Node *pre,*s;
int k;
if(i<=0) return;
pre=head;
k=0;
while(pre!=NULL&&k<i)
{
pre=pre->next;
k=k+1;
}
if(pre==NULL)
{
printf("WRONG PLACE");
return ;
}
s=(Node*)malloc(sizeof(Node));
s->data=e;
s->next=pre->next;
pre->next=s;
return;
}
void DelList(LinkList head,int i,char *e)//删除第i个结点并用e返回其值
{
Node *pre,*r;
int k;
pre=head;
k=0;
while(pre->next!=NULL&&k<i-1)
{
pre=pre->next;
k=k+1;
}
if(pre->next==NULL)
{
printf("WRONG PLACE");
return;
}
r=pre->next;
*e=r->data;
pre->next=r->next;
free(r);
return;
}
void DestroyList(LinkList head)//销毁链表
{
Node *p;
while(p->next!=NULL)
{
p=head->next;
head->next=p->next;
free(p);
}
}
int main()
{ char e;
Node *head;
head = (Node*)malloc(sizeof(Node));
head->next=NULL; //此步是头插法必须的,尾插法不必须
printf("头插法建表(输入数据为):\n");
CreatFromTail(head);
OutputList(head);
printf("输出前三个数据的地址:\n");
for(int i=1;i<4;i++)printf("%d ",&*Get(head,i));//注意要取结点的地址
printf("当前链表长度为%d\n",ListLength(head));
printf("在第二个元素后插入K后链表为:\n");
InsList(head,2,'K');
OutputList(head);
printf("删除第4个元素后链表为:\n");
DelList(head,4,&e);
OutputList(head);
printf("删除的元素值为%c\n",e);
printf("销毁链表!");
DestroyList(head);
return 0;
}
总结
这篇只是单链表一些简单的操作,本人能力有限,可能有所纰漏,望大家批评指教