1.冒泡排序
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
struct node
{
int data;
struct node *next;
}*head,*p,*q,*tail;
int main()
{
int i,n,t;
/*-------------------------------------------------------*/
scanf("%d",&n);
head=(struct node*)malloc(sizeof(struct node));
head->next=NULL;
tail=head;
for (i=1;i<=n;i++)
{
p=(struct node*)malloc(sizeof(struct node));
scanf("%d",&p->data);
p->next=NULL;
tail->next=p;
tail=p;
}//读入
/*-------------------------------------------------------*/
for (p=head->next;p!=NULL;p=p->next)
for (q=p->next;q!=NULL;q=q->next)
if (p->data>q->data)
{
t=p->data;
p->data=q->data;
q->data=t;
}
//上面的是用链表实现的冒泡排序;
/*-------------------------------------------------------*/
p=head->next;
printf("%d",p->data);
while (p->next!=NULL)
{
printf(" %d",p->next->data);
p=p->next;
}
//输出有序链表;
return 0;
}
2.快速排序(本地AC就是AC了,OJ上TLE都是假的)
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
struct Node
{
int data;
struct Node *next;
}*head,*p,*tail;
/*-------------------------------------------------------*/
void QuickSort(struct Node *head,struct Node *tail)
{
if(head == NULL||head == tail) return ;
int pivot = head->data;
struct Node *p = head;
struct Node *q = p->next;
while(q != tail)
{
if(q->data <pivot) //每次都选择待排序链表的头结点作为划分的基准
{
p = p->next;
int tmp = p->data; //p指针指向比基准小的节点组成的链表
p->data = q->data;
q->data =tmp;
}
q=q->next;
}
int tmp = p->data;
//此时p指向比基准小的节点组成的链表的最后一个节点,也就是基准元素,所以要与基准元素交换
p->data = head->data;
head->data =tmp;
QuickSort(head,p);
//比基准元素小的链表
QuickSort(p->next,NULL);
//右边是比基准大的节点组成的链表
}
//MMP比冒泡都慢的快排
/*-------------------------------------------------------*/
int main()
{
int i,n;
head=(struct Node *)malloc(sizeof(struct Node));
head->next=NULL;
tail=head;
scanf("%d",&n);
for (i=1;i<=n;i++)
{
p=(struct Node *)malloc(sizeof(struct Node));
scanf("%d",&p->data);
p->next=NULL;
tail->next=p;
tail=p;
}
QuickSort(head,tail);
p=head->next;
while(p!=NULL)
{
printf("%d ",p->data);
p=p->next;
}
printf("\n");
return 0;
}
3.重复数值的删除
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
struct node
{
int data;
struct node *next,*fron;
}*head,*p,*tail,*q,*r;
/*-------------------------------------------------------*/
int main()
{
int i,n,num=0;
scanf("%d",&n);
head=(struct node*)malloc(sizeof(struct node));
head->next=NULL;
tail=head;
for (i=1;i<=n;i++)
{
p=(struct node*)malloc(sizeof(struct node));
scanf("%d",&p->data);
p->next=head->next;
head->next=p;
}
//逆序建立链表
/*-------------------------------------------------------*/
p=head->next;
q=p;
while (p!=NULL)
{
while (q->next!=NULL)
{
if (p->data==q->next->data)
{
r=q->next;
q->next=r->next;
free(r);
num++;
}
else q=q->next;
}
p=p->next;
q=p;
}
//重复数值删除
/*-------------------------------------------------------*/
printf("%d\n",n-num);
p=head->next;
printf("%d",p->data);
while (p->next!=NULL)
{
printf(" %d",p->next->data);
p=p->next;
}
printf("\n");
//输出删减完毕后的链表
/*-------------------------------------------------------*/
return 0;
}
4.扩展二叉树
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <stdlib.h>
struct tree
{
char a;
struct tree *lchild,*rchild;//二叉树的左右子树
};
char s[233];
int i,j,k;
struct tree *root;//记录根节点
struct tree * build(struct tree *t);
void printzx(struct tree *t);
void printhx(struct tree *t);
void del(struct tree *t);
void printchild(NODE *t);
int printdeep(NODE *t);
int main()
{
struct tree *t;
char c;
while (~scanf("%s",s))
{
root=NULL;//这里根节点要初始化,不然对于空树情况会出错
scanf("%c",&c);
i=-1;
t = build(t);
printzx(root);
printf("\n");
printhx(root);
printf("\n");
//del(root);del函数有毛病,没有调用
}
return 0;
}
struct tree * build(struct tree *t)
//因为要用链表建树
//所以这里吧建树函数定义成struct tree *类型的
//主要目的是把建立的各个节点链接起来
{
i++;
if (s[i]!=',')
{
t=(struct tree *)malloc(sizeof(struct tree));
t->a=s[i];
if (i==0) root=t;
t->lchild = build(t->lchild);
t->rchild = build(t->rchild);
//这里是把新建立的节点连接起来
//如果没有这句话,相当于新建立了很多节点而没有把这些节点链接起来
//至于为什么会这样,需要自己慢慢体会
}
else t=NULL;
return t;
}
void printzx(struct tree *t)
//输出中序遍历
{
if (t!=NULL)
{
printzx(t->lchild);
printf("%c",t->a);
printzx(t->rchild);
}
else return;
}
void printhx(struct tree *t)
//输出后序遍历
{
if (t!=NULL)
{
printhx(t->lchild);
printhx(t->rchild);
printf("%c",t->a);
}
else return;
}
void del(struct tree *t)
//删除整棵树
{
if (t!=NULL)
{
del(t->lchild);
del(t->rchild);
free(t);
}
else return;
}
void printchild(NODE *t)
//找叶子节点的个数
{
if (t==NULL) return;
if (t->lchild!=NULL) printchild(t->lchild);//如果左边有孩子就搜左边
if (t->rchild!=NULL) printchild(t->rchild);//如果右边有孩子就搜右边
if (t->rchild==NULL&&t->lchild==NULL) num++;//printf("%c",t->a);
//如果两边都没有孩子说明是叶子节点
return;
}
int printdeep(NODE *t)
{
if (t!=NULL)
{
int nleft=printdeep(t->rchild);
//如果左边可以递归就递归左边,右边可以就递归右边
int nright=printdeep(t->lchild);
return nleft>nright?nleft+1:nright+1;
//返回值是左右边深度的最大值+1
}
return 0;
}
5.已知先序遍历求后续遍历(已知后序遍历和中序遍历求先序遍历)
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
typedef struct tree
{
char a;
struct tree *lchild,*rchild;
}TREE;
TREE *build(int n,char *pre,char *mid);
int main()
{
char pre[233],mid[233];
scanf("%s%s",pre,mid);
build(strlen(pre),pre,mid);
printf("\n");
return 0;
}
TREE *build(int n,char *pre,char *mid)
//已知先序中序求后续
{
TREE *root;
int i=0;
if (n==0) return NULL;
while (pre[0]!=mid[i]) i++;
//找到根节点在后序遍历的位置
root=(TREE *)malloc(sizeof(TREE));
root->a=pre[0];
//前序遍历的第一个字符必然是根节点
root->lchild=build(i,pre+1,mid);
//左子树的长度,左子树在先序遍历的开始地址,左子树在中序遍历的开始地址
root->rchild=build(n-i-1,pre+i+1,mid+i+1);
//右子树的长度,右子树在先序遍历的开始地址,右子树在中序遍历的开始地址
printf("%c",root->a);
//输出后续遍历
return root;
}
TREE *build(int n,char *fina,char *mid)
//已知中序后序求前序
{
TREE *root;
int i=0;
if (n<=0) return NULL;
while (mid[i]!=fina[n-1]) i++;
root=(TREE *)malloc(sizeof(TREE));
root->a=fina[n-1];
printf("%c",root->a);
//后序遍历:____left____right_root
//中序遍历:____left_root____right
root->lchild=build(i,fina,mid);
root->rchild=build(n-i-1,fina+i,mid+i+1);
return root;
}
6.双向队列(其实就是双向链表)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#define true 1
#define false 0
struct node
{
int data;
struct node *left,*right;
}*head,*p,*tail;
char LIN[]="LIN",RIN[]="RIN",LOUT[]="LOUT",ROUT[]="ROUT";
struct node *leftadd(struct node *head,int x);
struct node *rightadd(struct node *tail,int x);
_Bool leftdel(struct node *head);
_Bool rightdel(struct node *tail);
int main()
{
int n,i,x,a[10001];
char type[23];
scanf("%d",&n);
for (i=0; i<=n; i++) a[i]=0;
head=(struct node *)malloc(sizeof(struct node));
head->right=NULL;
tail=head;
for (i=1; i<=n; i++)
{
scanf("%s",type);
if (!strcmp(type,LIN))
{
scanf("%d",&x);
head=leftadd(head,x);
}
else if (!strcmp(type,RIN))
{
scanf("%d",&x);
tail=rightadd(tail,x);
}
else if (!strcmp(type,LOUT))
{
if (leftdel(head)) continue;
else a[i]=1;
}
else if (!strcmp(type,ROUT))
{
if (rightdel(tail)) continue;
else a[i]=1;
}
}
p=head->right;
while (p->right!=NULL)
{
printf("%d ",p->data);
p=p->right;
}
printf("%d\n",p->data);
for (i=0; i<=n; i++) if (a[i])
printf("%d ERROR\n",i);
return 0;
}
struct node *leftadd(struct node *head,int x)
{
p=(struct node *)malloc(sizeof(struct node));
p->data=x;
p->right=head->right;
head->right=p;
head->right->left=p;
return head;
}
struct node *rightadd(struct node *tail,int x)
{
p=(struct node *)malloc(sizeof(struct node));
p->data=x;
p->right=NULL;
p->left=tail;
tail->right=p;
tail=p;
return tail;
}
_Bool leftdel(struct node *head)
{
if (head->right==NULL) return false;
else
{
struct node *r;
r=head->right;
r->right=head->right;
free(r);
}
return true;
}
_Bool rightdel(struct node *tail)
{
if (tail==head) return false;
else
{
struct node *r;
r=tail->left;
tail->left=r->left;
tail=r->left;
free(r);
}
return true;
}