单链表
#include <stdio.h>
#include <math.h>
#include <malloc.h> //不要丢掉
#include <string.h>
#include <conio.h>
#define NULL0
typedefstruct student
{
int data;
struct student * next;
} node;
//----------------------------------------------
node* creat(int n) //1
node *head = NULL, *p = NULL, *s = NULL;
int x;
head = (node*)malloc(sizeof(node));
p = head;
for (int i = 1; i <= n; i++) //用一个n次循环来处理
{
printf("第%d个数据是:", i);
scanf("%d;", &x);
s = (node *)malloc(sizeof(node));
s->next = NULL;
s->data = x;
p->next = s;
p = s;
}
return (head);
}
//----------------------------------------------
int ListEmpty(node* h) //返回1说明是空的
{
return (h->next == NULL);
}
//--------------------------------------------
void Display(node *h)
{
node *p = h->next;
if (p == NULL)
{
printf("List isempty");
return;
}
while (p != NULL) //这里比较的不是p->next;
{
//每个元素都可以处理到,循环n次处理n个元素
printf("%d ", p->data);
p = p->next;
}
printf("\n");
}
//------------------------------------------------
int Length(node *h)
{
node *p = h;
int i = 0; //i是用来记录循环次数的
while (p->next)
{
i++;
p = p->next;
}
return i;
}
//------------------------------
void GetElem(node* h, int i, int &e) // 找到单链表h中第i个元素
{
node *p = h;
int j = 0;
if (p == NULL)
{
printf("List isempty");
return;
}
while ((j < i) && p->next)
{
j++;
p = p->next;
}
if (p->next == NULL)
{
printf("没有第%d个元素\n", i);
}
else
{
e = p->data;
printf("第%d个元素为:%d\n", i, e);
}
}
//-----------------------------------------------
void LocateElem(node *h, int e) // 寻找给定元素在表中的位置标号
{
node *p = h->next;
int i = 1; //跟p不配套了
if (p == NULL)
{
printf("List isempty");
return;
}
while (p && (p->data != e))
{
p = p->next; //此时i跟p是配套的
i++;
}
if (p == NULL)
{
printf("没有第%d这个元素\n", e);
}
else
{
printf("%d在链表的第%d个位置\n", e, i);
}
}
int Insert(node* &h, inti, int e) // 在第i个元素前插入一个元素
{
node* p = h;
node* s;
int j = 0;
while ((j < i - 1) && p) //选择p是为了能在最后一个元素后插入元素
{
j++;
p = p->next;
}
if (p == NULL)
{
printf("i范围错误");
return 0;
}
else
{
s = (node*)malloc(sizeof(node));
s->next = p->next;
s->data = e;
p->next = s;
return 1;
}
}
int Del(node*&h, inti) // 删除第i个元素
{
//要删除一个节点,p是不可能走到最后一个节点的。
int j = 0;
node* p = h;
node*q = NULL;
if (p->next == NULL)
{
//printf("List isempty");
return 0;
}
while ((j < i - 1) && p->next)
{
j++;
p = p->next;
}
if (p->next == NULL)
{
//printf("i超出范围");
return 0;
}
else
{
q = p->next; //q=0
p->next = q->next; //q=0->next
free(q);
return 1;
}
}
void destroy(node*&h) // 释放链表
{
node*p = h;
node*q = p->next;
while (q != NULL)
{
free(p);
p = q;
q = q->next;
}
free(p);
}
void reverse(node*&h)
{
node*q1 = h->next,;
node*q2 = q1->next;
node*temp;
q1->next = NULL;
while (q2) //至少有两个元素才好反转
{
temp = q2->next;
q2->next = q1;
q1 = q2;
q2 = temp;
}
h->next = q1; //q1指向最后一个节点
}
node* bubble_sort(node*&h, int size) //因为链表是单向的,所以选择下沉石头
{
int i, j, temp;
node*p = h->next;
for (j = size - 1; j >= 1; j--)
{
p = h->next;
for (i = 0; i + 1 <= j; i++)
{
if (p->next->data < p->data)
{
temp = p->next->data;
p->next->data = p->data;
p->data = temp;
}
p = p->next;
}
}
return h;
}
双链表
typedefstruct DNode
{
int data;
struct DNode *prior;
struct DNode *next;
}node;
voidInit(node *&h)
{
h=(node*)malloc(sizeof(node));
h->prior=h->next=0;
}
插入节点
intInsert(node *&h,int i,int e)
{
int j=0;
node*p=h;
node*s=null;
while(p&&j<i-1)
{
j++;
p=p->next;
}
if(p==null)
{
printf("为找到第%d个节点\n",i-1);//未找到地i-1个节点
return 0;
}
else
{
s=(node*)malloc(sizeof(node));
s->data=e;
if(p->next!= NULL) p->next->prior=s;//如果是要在最后一个元素后面插入这句话就可以省掉
s->prior=p;
s->next=p->next;
p->next=s;
return 1;
}
}
删除节点
intDeleteElem(node*&h,int i)//要删除一个节点,p是不可能走到最后一个节点的。
{
int j=0;
node*p=h;
node*q=null;
while(j<i-1&&p->next)
{
j++;
p=p->next;
}
if(p->next==null)
{
printf("找到地%d个节点\n",i-1);//未找到地i-1的节点,如果要删除节点的前一个节点是最后一个节点的话
return 0;
}
else
{
q=p->next;//q指向要删除的节点
p->next=q->next;//0
if(p->next != null)//如果删除的是最后一个节点
p->next->prior=p;
free(q);
return 1;
}
}
循环单链表
typedefstruct LNode
{
char data;
struct LNode *next;
}node;
voidInit(node*&h)
{
h=(node*)malloc(sizeof(node));
h->next=h;
}
voidDestroy(node*&h) //引起注意
{
node*p=h;
node*q=p->next;
while(q!=h)//注意这里和单链表不一样
{
free(p);
p=q;
q=p->next;
}
free(p);
}
voidEmpty(node *h)
{
if(h->next==h)
printf("list is empty!\n");
else
printf("list is notempty\n");
}
voidLength(node*h)
{
node*p=h->next;
int i=0;
while(p!=h)
{
i++;
p=p->next;
}
printf("length is %d\n",i);
}
voidDisplay(node*h)
{
node*p=h->next;
if(null==h)
printf("list is empty!\n");
while(p!=h)
{
printf("%c ",p->data);
p=p->next;
}
}
voidGetElem(node*h,int i)
{
int j=0;
node*p=null;
if(h->next!=null)
printf("list is empty\n");
p=h->next;
while(p!=h)
{
j++;
p=p->next;
}
if(h==p)
printf("cant get theelem!\n");
else
{
printf("the elemis%c\n",p->data);
}
}
voidLocate(node*h,char e)
{
node*p=h->next;
int i=0;
while(p!=h && p->data!=e)
{
p=p->next;
i++;
}
if(p==h)
printf("cant do it !\n");
else
printf("the number of %c is%d\n",e,i);
}
插入
voidInsert(node*h,int i,char e)//插入节点就两句话
{
int j=0;
node*p=h;
node*s=null;
while(p!=h&&j<i-1)
{
j++;
p=p->next;
}
if(p==h)
{
printf("未找到第%d个节点\n",i-1);//未找到地i-1个节点
}
else
{
s=(node*)malloc(sizeof(node));
s->data=e;
s->next=p->next;//1
p->next=s;//2
}
}
删除
void del(node*&h,int i)
{
int j=0;
node*p=h;
node *q=null;
if(p->next==null)
{
printf("List isempty");
return 0;
} if
while(j<i-1&&p->next!=h)
{
j++;
p=p->next;
}
if(p->next==h)
{
printf("未找到地%d个节点\n",i-1);
}
else
{
q=p->next;//q指向要删除的节点
p->next=q->next;//0
free(q);
}
}
栈
//栈是一个简单的链表,只有push(),pop(),top(),display()几个操作
#include<stdio.h>
#include<malloc.h>
#define NULL0
typedef struct stack
{
int data;
struct stack *next;
}node;
voidInitStack(node* &h)
{
h=(node*)malloc(sizeof(node));
h->next=NULL;
}
栈长(跟链表一样)
intLength(node* h)
{
int i=0;
node* p=h;
while(p->next)
{
i++;
p=p->next;
}
//printf("链表的长度为%d\n",i);
return i;
}
Push
void Push(node* &h,int e)//实际上就是在第一个节点前插入数据
{ //处理h后的一个节点
node* s;
s=(node*)malloc(sizeof(node));
s->data=e;
s->next=h->next;
h->next=s;
}
Pop
intpop(node* &h)//实际上就是删除第一个节点
{ //处理h后的一个节点
node* p=h;
int e;
if(p->next==0)
{
printf("Stack isempty!\n");
return 0;
}
p=p->next;//指向第一个节点
//e=p->data;
h->next=p->next;
free(p);
//printf("弹出的元素是:%d\n",e);
return 1;
}
Top
intTop(node*h)//实际上就是读取第一个数据
{
node*p=h;
int e;
if(p->next==NULL)
{
printf("Stack isempty");
return 0;
}
e=p->next->data;
printf("顶点的数为%d\n",e);
return e;
}
打印(跟链表一样)
voiddispaly(node* h)
{
node *p=h->next;
if(p==NULL)
{
printf("Stack isempty!\n");
return;
}
while(p!=NULL)//这里比较的不是p->next;
{ //每个元素都可以处理到,循环n次处理n个元素
printf("%d ",p->data);
p=p->next;
}
printf("\n");
}
voiddestroy(node*&h) // 释放链表
{
node*p=h;
node*q=p->next;
while(q!=NULL)
{
free(p);
p=q;
q=q->next;
}
free(p);
}
/*
队列
//队列,就是enqueue(),front(),dequeue(),display()一些函数
//用链表来表示
#include<stdio.h>
#include<malloc.h>
#define NULL0
typedefstruct student
{
int data;
struct student *next;
}node;
typedef struct linkqueue
{
node*front;
node*rear;
}queue;
void Init(queue*&q)
{
q=(queue*)malloc(sizeof(queue));
q->front=q->rear=NULL;
}
测长
int Length(queue*h)
{
inti=0;
node*p=h->front;//赋值有少许变化,把第一个元素的地址发给了p
while(p) //p跟i不同步了
{
i++;
p=p->next;
}
returni;
}
int Empty(queue*h)
{
if(h->rear==NULL)
return 1;
else
return 0;
}
入队
queue*enQueue(queue *&h,inte)//想象成人们在排队
{
node *s;
s=(node*)malloc(sizeof(node));
s->data=e;
s->next=NULL;//插入一个元素,排在最后,从后面插入
if(h->rear==NULL)//若队列为空
h->front=h->rear=s;
else
{
node *b=h->rear;
b->next=s;//h->rear->next=s;
h->rear=s;
}
return h;
}
出队
intdeQueue(queue *&h)
{
node *t;
if(h->rear==NULL)
{
printf("Queue isempty!");
return 0;
}
if(h->front==h->rear)//队列中只有一个节点时
{
t=h->front;
h->front=h->rear=NULL;
}
else
{
t=h->front;
h->front=t->next;
}
free(t);
return 1;
}
void Clear(queue*&h)
{
node *p=h->front;//p指向第一个节点
node *r=NULL;
if(p)
{
r=p->next;
while(r!=NULL)
{
free(p);
p=r;
r=p->next;
}
}
free(h);
}
打印
voiddisplay(queue *h)
{
node* p=h->front;//p指向第一个节点
if(h->rear==NULL)
printf("Queue is empyt!\n");
while(p)
{
printf("%d ",p->data);
p=p->next;
}
printf("\n");
}
约瑟夫问题(猴子选大王)
循环链表C语言实现
Slyar2009.3.31
http://www.slyar.com
*/
#include<stdio.h>
#include<stdlib.h>
/* 定义链表节点类型 */
typedefstruct node
{
int data;
struct node *next;
}linklist;
int main()
{
int i, n, k, m, total;
linklist *head, *p, *s, *q;
/* 读入问题条件 */
printf("请输入猴子的个数:");
scanf("%d", &n);
printf("请输入要从第几个猴子开始报数:");
scanf("%d", &k);
printf("请输入出局数字:");
scanf("%d", &m);
/* 创建循环链表,头节点也存信息 */
head = (linklist*)malloc(sizeof(linklist));
p = head;
p->data = 1;
p->next = p;
/* 初始化循环链表 */
for (i = 2; i <= n; i++)
{
s = (linklist*)malloc(sizeof(linklist));
s->data = i;
s->next = p->next;
p->next = s;
p = p->next;
}
/* 找到第 k 个节点 */
p =head;
for (i = 1; i < k; i++)
{
p = p->next;
}
/* 保存节点总数 */
total = n;
printf("\n出局序列为:");
q = head;
/* 只剩一个节点时停止循环 */
while (total != 1)
{
/* 报数过程,p指向要删除的节点 */
for (i = 1; i < m; i++)
{
p = p->next;
}
/* 打印要删除的节点序号 */
printf("[%d] ", p->data);
/* q 指向 p 节点的前驱 */
while (q->next != p)
{
q = q->next;
}
/* 删除 p 节点 */
q->next = p->next;
/* 保存被删除节点指针 */
s = p;
/* p 指向被删除节点的后继 */
p = p->next;
/* 释放被删除的节点 */
free(s);
/* 节点个数减一 */
total--;
}
/* 打印最后剩下的节点序号 */
printf("\n\n猴子大王为第 [%d] 号\n\n", p->data);
free(p);
//system("pause");
return 0;
}