链表总结起来可以归结为一个递归结构体指针
链表主要的基本的操作:
建立一个有表头的链表:
有表头单向链表:
有表头单项环表:
建立一个无表头的链表:
无表头单向链表:
无表头单项环表:
主要有向链表中插入一个数据、删除一个数据、遍历一个链表输出想要的元素值、遍历链表求链表的长度、基本应用;
#include "stdio.h"
#include <stdlib.h>
#include "string.h"
struct node{
int no;
struct node *next;
};
typedef struct node NODE;
/*创造节点数据内容为 1 —— n*/
void cre_node(NODE *head,int n)
{
NODE *p;
//while(n-->0) 只能输出0 —— n-1 n个数
for(;n>0;n--) //1 —— n n个数
{
p=(NODE *)malloc(sizeof(NODE));
p->no=n;
p->next=head->next;
head->next=p;
}
}
void put_node(NODE *head)
{
NODE *p=head->next;
while(p!=NULL)
{
printf("%3d",p->no);
p=p->next;
}
}
int node_len(NODE *head)
{
NODE *p=head->next;int len;
for(len=0;p!=NULL;len++)
p=p->next;
return len;
}
/****在第i个节点后面加入元素****/
void insert_node(NODE *head,int i)
{
NODE *p,*q;int n;
p=head;
for (n=0;n<i&&p->next!=NULL;++n)
p=p->next; //定位
q=(NODE *)malloc(sizeof(NODE));
printf("\n输入插入元素数据:");
scanf("%d",&(q->no));getchar();
q->next=p->next;
p->next=q;
}
/**删除第i个节点**/
void delete_node(NODE *head,int i)
{
NODE *p,*q;int n;
for (p=head,n=0;n<i-1&&p->next!=NULL;++n)
p=p->next;
//q=(NODE *)malloc(sizeof(NODE));
if(n==i-1&&p->next!=NULL)
{
q=p->next;
p->next=q->next;
}
free(q);
}
int main(){
NODE *p,*q,*head;
int i,k;
p=(NODE *)malloc(sizeof(NODE));
p->next=NULL;
head=p;
cre_node(head,30);
put_node(head);
insert_node(head,2);
//printf("\nlen=%d\n",node_len(head));
put_node(head);
printf("\n");
//printf("\nlen=%d\n",node_len(head));
delete_node(head,3);
put_node(head);
getchar();
return 0;
}
约瑟夫问题
int main(){
NODE *p,*q,*head;
int i,k;
head=(NODE *)malloc(sizeof(NODE));
head->no=-1; //表头节点标志示以区别
head->next=head;
for(i=30;i>0;--i)
{
p=(NODE *)malloc(sizeof(NODE));
p->no=i;
p->next=head->next;
head->next=p;
}
while(p->no!=30)//这样是定位到第p位,看第p位的标志的数据
//while(p->next!=head)//这样是定位到第p+1位,看第p+1位的指针标志的数据
p=p->next;
printf("%d",p->no);
// q=p->next;
// p->next=q->next; //同一个结构指针,可以当作中间变量多次使用;
p->next=head->next;
for(i=0;i<15;i++)
{
for(k=0;k<8;k++)
p=p->next;
q=p->next;
printf("%3d",q->no);
p->next=q->next;
free(q);
}
getchar();
return 0;
}