单链表
#include<stdio.h>
#include<stdlib.h>
typedef int datekey;
typedef struct link_node
{
datekey info;
struct link_node *next;
}node;
node *init()
{
return NULL;
}
void display(node *head)//输出各个节点的值
{
node *p;
p=head;
if(p==NULL)
{
printf("链表是空的\n");
exit(1);
}
while(p)
{
printf("%-5d",p->info);
p=p->next;
}
printf("\n");
}
node *find(node *head,int i)//返回第i个节点的地址
{
int j=1;
node *p=head;
if(i<1) return NULL;
while(p&&i!=j)
{
p=p->next;
j++;
}
return p;
}
node *insert(node *head,datekey x,int i)//在第i个节点插入键值为x的节点
{
node *p,*q;
q=find(head,i);
if(!q&&i!=0)
{
printf("找不到%d节点",i);
exit(1);
}
p=(node *)malloc(sizeof(node));
p->info=x;
if(i==0)
{
p->next=head;
head=p;
}else {
p->next=q->next;
q->next=p;
}
return head;
}
node *dele(node *head,datekey x) //删除键值为x的节点
{
node *pre=NULL;
node *p=head;
if(!head)
{
printf("链表是空的\n");
exit(1);
}
while(p&&p->info!=x) pre=p,p=p->next;
if(p)
{
if(!pre) head=p->next;
else pre->next=p->next;
free(p);
}
return head;
}
int main()
{
int i=0,n;
while(~scanf("%d",&n))
{
node *head;
head=init(head);
for(i=0;i<n;i++)
{
int x;
scanf("%d",&x);
head=insert(head,x,i);
}
printf("请输入要插入的值和节点\n");
int a,b;
scanf("%d%d",&a,&b);
head=insert(head,a,b);
display(head);
printf("输入要删除的值:\n");
scanf("%d",&n);
dele(head,n);
display(head);
}
}
带头结点的单链表
#include<stdio.h>
#include<stdlib.h>
#define maxn 1111
typedef int datekey;
typedef struct link_node
{
datekey info;
struct link_node *next;
}node;
node *init()
{
node *head=(node *)malloc(sizeof(node));
head->next=NULL;
return head;
}
node *find(node *head,int i)
{
int j=0;
node *p=head;
if(i<0)
{
printf("不存在这样的节点\n");
exit(1);
}
while(p&&i!=j) p=p->next,j++;
return p;
}
node *insert(node *head,datekey x,int i)
{
node *p=find(head,i);
if(!p)
{
printf("不存在这样的节点\n");
exit(1);
}
node *q=(node*)malloc(sizeof(node));
q->info = x;
q->next=p->next;
p->next=q;
return head;
}
void display(node* head)
{
node *p=head;
p=p->next;
if(!p)
{
printf("表是空的\n");
exit(1);
}
while(p) printf("%-5d",p->info),p=p->next;
printf("\n");
}
node *dele(node* head, datekey x)
{
node *pre=head;
node *p=head->next;
while(p&&p->info!=x) pre=p,p=p->next;
if(p)
{
pre->next=p->next;
free(p);
}
return head;
}
int main()
{
int n,i;
datekey x;
while(~scanf("%d",&n))
{
node *head;
head=init();
for(i=0;i<n;i++)
{
scanf("%d",&x);
head=insert(head,x,i);
}
display(head);
printf("要插入的数和节点\n");
scanf("%d%d",&x,&i);
insert(head,x,i);
display(head);
printf("输入要删除的数\n");
scanf("%d",&x);
dele(head,x);
display(head);
}
}
循环链表
#include<stdio.h>
#include<stdlib.h>
typedef int datetype;
typedef struct link_node
{
datetype info;
struct link_node *next;
}node;
node * init()
{
return NULL;
}
node *create() //创建一个个循环链表,以输入-1结束
{
int x;
node *head=(node *)malloc(sizeof(node)),*p,*q;
scanf("%d",&x);
if(x!=-1) head->info=x;
else return NULL;
p=head; //p始终指向表的末尾
while(scanf("%d",&x)&&x!=-1)
{
q=(node *)malloc(sizeof(node));
q->info=x;
p->next=q; //p指向插入的节点的地址
p=p->next; //p指向表的末尾
}
p->next=head; //循环链表,表的末尾指向头指针
return head;
}
void display(node *head) //输出表的内容
{
node *p=head;
if(!head)
{
printf("循环链表是空的\n");
}
else
{
p=head->next; //先输出头结点的值
printf("%-5d",head->info);
while(p!=head) //当再一次指向头结点时,链表遍历完全
{
printf("%-5d",p->info);
p=p->next;
}
}
printf("\n");
}
node *find_rear(node *head) //找到表的尾指针
{
node *p=head;
if(!head) return NULL;
while(p->next!=head) p=p->next; //若当前节点的指向的是头指针,循环结束
return p;
}
node *insert(node *head,int i,datetype x) //链表中在第i节点后插入键值为x的节点
{
node *p=head,*q,*rear;
rear=find_rear(head); //找到尾指针
int j=1; //计数从1始,指向当前头节点
q=(node *)malloc(sizeof(node));
q->info=x;
if(i<0)
{
printf("这样的节点不存在\n");
return NULL;
}
if(i==0&&!head) //若链表为空且插入的点在第0位
{
head=q,head->next=head;//直接接将将待插入点改为头结点并指向自己
return head;
}
if(i==0&&head) //若插入节点在头部,但链表不为空
{
q->next=head,head=q; //将待插入点指向原来的头结点,改变头结点
rear->next=head; //使尾指针指向新的头结点
return head;
}
if(i>0&&!head) //节点大于0,且链表为空,不存在
{
printf("无法找到这样的节点\n");
return head;
}
while(p->next!=head&&i!=j) p=p->next,j++; //节点大于1,链表不为空,扫描链表,找到第i个节点
if(i>0&&i==j) //找到节点,进行插入
{
q->next=p->next;
p->next=q;
}else if(i!=j) printf("不存在这样的节点\n");
return head;
}
node *dele(node *head,datetype x)
{
node *pre=NULL,*p=head;
if(!head)
{
printf("链表是空白的\n");
return head;
}
while(p->next!=head&&p->info!=x) pre=p,p=p->next; //pre始终指向p节点的前驱
if(p->info!=x)
{
printf("不存在这样的点\n");
return head;
}
if(head->info==x) //要删除头节点时
{
if(head->next==head) //链表只有头结点,则返回空
{
free(head);
return NULL;
}
else //否则找到到尾指针,使得尾指针指向删除后新的头指针
{
pre=head->next;
while(pre->next!=head) pre=pre->next;
pre->next=head->next;
free(head);
head=pre->next;
}
}
else
pre->next=p->next,free(p);//删除的点在中间某个地方时,将p的前驱指向p的后继
return head;
}
int main()
{
node *head,*rear;
while(1)
{
int id,x;
head=create();
display(head);
printf("输入要插入的节点和值:");
scanf("%d%d",&id,&x);
head=insert(head,id,x);
display(head);
printf("输入要删除的值:");
scanf("%d",&x);
head=dele(head,x);
display(head);
}
}
双向链表
#include<stdio.h>
#include<stdlib.h>
typedef int datatype;
typedef struct dlink_list
{
datatype info;
struct dlink_list *llink,*rlink;//指向前驱的指针和指向后继的指针
}node;
node *init()
{
return NULL;
}
void display(node *head)//输出链表各节点的值
{
node *p=head;
if(!head) //链表为空
{
printf("链表是空的\n");
return NULL;
}
while(p)
{
printf("%-5d",p->info);
p=p->rlink;
}
printf("\n");
}
node *create() //创建一个双向链表,以输入-1结束
{
int x;
node *head,*p,*q;
head=(node *)malloc(sizeof(node));
scanf("%d",&x);
if(x!=-1) head->info=x,head->rlink=NULL,head->llink=NULL;
else {free(head);return NULL;}//若只输入-1,则释放申请的空间,返回空链表
p=head;//p始终指向当前链表的尾部
while(scanf("%d",&x)&&x!=-1)
{
q=(node *)malloc(sizeof(node));
q->info=x;
p->rlink=q; //尾部指向新插入的节点
q->llink=p; //使要插入的节点指向原链表的尾部
p=p->rlink;//p指向新链表的尾部
}
p=p->rlink=NULL; //使链表尾部指向NULL
return head;
}
node *insert(node* head, int i, int x) //插入一个新节点,插在第i的节点后面
{
int j=1;
node *p,*q;
q=(node *)malloc(sizeof(node));
q->info=x;
if(i<0)
{
printf("不存在这样的节点\n");
free(q);
return head;
}
if(i==0&&!head) //插在头结点前面并且此时链表为空
{
head=q; //直接将待插入点改为头结点
head->rlink=NULL; //前驱后继各指向空
head->llink=NULL;
return head;
}
if(i==0&&head) //插在头结点前面
{
q->rlink=head; //新的节点指向原头结点
head->llink=q; //原头结点的左指针指向新插入的节点
head=q; //改变头结点
head->llink=NULL;//使得新的头节点的左指针指向NULL
return head;
}
p=head;
while(p&&i!=j) p=p->rlink,j++; //当插入节点在中间某个地方时
if(p)
{
if(p->rlink==NULL) //插入的节点在尾部
{
p->rlink=q;//原链表的尾部的右指针指向新插入节点
q->llink=p;//新插入节点的左指针指向原链表尾部
p=p->rlink;//p指向当前指针待插入节点
p->rlink=NULL; //尾部的指针指向NULL
}
else
{
q->rlink=p->rlink; //使得新插入节点的右指针指向待插入节点的后一个节点
p->rlink=q; //使得当前节点指向
q->rlink->llink=q;//当前节点后一个节点的左指针指向待插入节点
q->llink=p; //待插入节点的左指针指向当前节点
}
return head;
}
else
{
printf("不存在这样的节点\n");
free(q);
return head;
}
}
node *dele(node* head, int x)
{
node *p=head;
if(!head)
{
printf("链表是空的\n");
return NULL;
}
while(p&&p->info!=x) p=p->rlink; //找到第一个等于x的节点,p指向待删除的节点
if(head->info==x)//头结点等于x的情况
{
if(head->rlink==NULL) free(p),head=NULL; //若只有头结点,返回空
else head=head->rlink,head->llink=NULL,free(p); //否则下一个作为头结点,头结点的左指针指向为空,释放空间
return head;
}
if(p) //当找到等于x的节点
{
if(p->rlink==NULL) p->llink->rlink=NULL,free(p); //删除的点在尾部,尾指针向前移
else
{
p->llink->rlink=p->rlink; // 当前节点的前驱指向当前节点的后继
p->rlink->llink=p->llink; //当前节点后继的左指针指向当前节点的前驱
free(p);
}
return head;
}
else
{
printf("不存在这样的节点\n");
return head;
}
}
int main()
{
int x,id;
node *head;
printf("创建一个链表:\n");
head=create();
display(head);
printf("输入要插入的节点和值:");
scanf("%d%d",&id,&x);
head=insert(head,id,x);
display(head);
printf("输入要删除的数据:");
scanf("%d",&x);
head=dele(head,x);
display(head);
}