一、绪论
1.数组中按值查找元素
cpp
复制代码
int Search(int a[],int n,int k){
for(int i=1;i<=n;i++){
if(a[i]==k){
return i;
}
}
return 0;
}
2.找最大值和次大值
cpp
复制代码
void FindMax(int a[],int n,int *pmax1,int *pmax2){
if(a[1]>a[2]){
*pmax1=a[1];
*pmax2=a[2];
}
else{
*pmax1=a[2];
*pmax2=a[1];
}
for(int i=3;i<=n;i++){
if(a[i]>*pmax1){
*pmax2=*pmax1;
*pmax1=a[i];
}
else if(a[i]>*pmax2){
*pmax2=a[i];
}
}
}
二、线性表
1.顺序表的逆置
cpp
复制代码
void reverse(SeqList *q){
int temp,i;
for(i=0;i<q->length/2;i++){
temp=q->elem[i];
q->elem[i]=q->elem[q->length-i-1];
q->elem[q->length-i-1]=temp;
}
}
2.单链表的逆置
cpp
复制代码
void reverse(SeqList *q){
int temp,i;
for(i=0;i<q->length/2;i++){
temp=q->elem[i];
q->elem[i]=q->elem[q->length-i-1];
q->elem[q->length-i-1]=temp;
}
}
3.找出顺序表中的最小值
cpp
复制代码
int FindMin(SeqList *q ) {
int i=0;
int min = q->elem[i];
for (i = 1; i < q->length; i++) {
if (q->elem[i] < min) {
min = q->elem[i];
}
}
for(i=0;i<q->length;i++){
if(min==q->elem[i])
break;
}
return i;
}
4.删除顺序表中的指定值元素
cpp
复制代码
void DeleteX(SeqList *q,ElemType x){
int flag=0;
for(int i=0;i<q->length;i++){
if(q->elem[i]!=x){
q->elem[flag]=q->elem[i];
flag++;
}
}
q->length=flag;
}
5.删除循环链表中已知结点的前驱
cpp
复制代码
void DelPrior(LNode *s){
int a;
LNode *p,*q;//q为要删除结点,即s的前驱;p为q的前驱结点
p=q=s;
while(q->next!=s){
q=q->next;
}
while(p->next!=q)
p=p->next;
a=q->data;
p->next=s;
free(q);
}
6.从单链表LA指定位置删除连续n个元素并插入单链表LB的指定位置
cpp
复制代码
void MoveLaToLb(LinkList *pa,int i,int len,LinkList *pb,int j) {
// m:遍历链表L;n:被删除链表头;p:被删除链表尾;q:遍历链表LB;r:若i不为1,则为被删除链表头结点的前一个元素
LinkList m, n, p, q, r;
int length = 1;
// 遍历LA记录链表长度
m = *pa;
while (m) {
length++;
m = m->next;
}
// 若不存在第i个元素或第i个元素后不足len个元素,则返回
if (i + len > length)
return;
// 遍历LB记录链表长度
q = *pb;
length = 0;
while (q) {
length++;
q = q->next;
}
// 若不存在第j个元素则返回
if (j > length)
return;
m = *pa;
// 1.从首元素开始删除
if (i == 1) {
// n标记被删除链表头结点
n = m;
for (int k=0;k<len-1;k++) {
m = m->next;
}
// p标记被删除链表尾结点
p = m;
// LA链表重构,链表头结点为被删除尾元素的下一结点
*pa = m->next;
}
else {
// 2.从中间元素开始删除
for (int k=0;k<i-2;k++) {
m = m->next;
}
// r用来标记被删除链表头结点的前一结点(方便重新连接LA链表)
r = m;
// n标记被删除链表头结点
n = m->next;
for (int k=0;k<len;k++) {
m = m->next;
}
// p标记被删除链表尾结点
p = m;
// 重新连接LA链表
r->next = p->next;
}
q = *pb;
if (!j) {
// 1.头插:直接连接LB头结点
p->next = q;
// LB头结点设置为n
*pb = n;
}
else {
for (int k=0;k<j-1;k++) {
q = q->next;
}
// 2.从中间插入(先连接右边,再连接左边)
p->next = q->next;
q->next = n;
}
}
7.两个单链表元素的交叉合并
cpp
复制代码
LinkList CombineList(LinkList La,LinkList Lb)
{
LNode *p,*q,*r;
LinkList Lc;//建立头指针
int m=0,n=0;
p = La->next;
q = Lb->next;
while(p)
{
++m;
p = p->next;//遍历La链表,求出La的长度
}
while(q)
{
++n;
q = q->next;//遍历Lb链表,求出La的长度
}
p = La->next;//因为遍历过后p,q都为空,所以需要让他们重新指向第一个节点
q = Lb->next;
if(m <= n)
{
Lc = La;//m <= n,说明此时La链表比Lb链表短,那么先从La开始,
r = Lc; //让Lc指向La所指的,就是说从La开始,就不用申请空间
//建立新的链表了
while(p && q)
{
r->next = p;//有头节点,r就只向p,然后p后移,r再指向q,q后移
r = p; //直到p为空,因为p短,先结束
p = p->next;
r->next = q;
r = q;
q = q->next;
}
while(q)
{
r->next = q;//p执行完了,剩下的都是q
r = q;
q = q->next;
}
free(Lb);
}
else
{
Lc = Lb;
r = Lc;
while(p && q)
{
r->next = q;
r = q;
q = q->next;
r->next = p;
r = p;
p = p->next;
}
while(p)
{
r->next = p;
r = p;
p = p->next;
}
free(La);
}
return (Lc);
}
三、栈和队列
1.使用栈进行回文判断
cpp
复制代码
int IsPalindrome(char s[]){
int len = strlen(s);
SeqStack *stack = InitStack();
int mid = len/2;
for(int i=0;i<mid;i++){
Push(stack,s[i]);
}
if(len%2!=0)
mid++;
for(int i=mid;i<len;i++){
char flag;
if(Pop(stack,&flag)==FALSE)
return 0;
if(flag!=s[i])
return 0;
}
return 1;
}
2.判断表达式中括号是否匹配
cpp
复制代码
int IsBracketMatch(char *str){
SeqStack *stack = InitStack();
char flagChar,leftChar;
for(int i=0;(flagChar=str[i])!='\0';i++){
if(flagChar=='['||flagChar=='{'||flagChar=='('){
Push(stack,flagChar);
}
else if(flagChar==']'||flagChar=='}'||flagChar==')')
{
if(IsEmpty(stack))
return 0;
Pop(stack,&leftChar);
if((flagChar==']'&&leftChar!='[')||
(flagChar=='}'&&leftChar!='{')||
(flagChar==')'&&leftChar!='('))
return 0;
}
}
return IsEmpty(stack)?1:0;
}
3.队列的操作集合(带尾指针的循环链表)
cpp
复制代码
// 初始化队列:创建头节点,尾指针指向头节点,头节点的next指向自身
CirLinkQueue InitQueue() {
LNode *head = (LNode *)malloc(sizeof(LNode));
// 空队列中,头节点的next指向自身
head->next = head;
return head;
}
// 判断队列是否为空:头节点的next指向自身则为空
int IsEmptyQueue(CirLinkQueue Q) {
// 队列为空的条件:尾指针的next(头节点)的next指向自身
return (Q->next->next == Q->next) ? 1 : 0;
}
// 入队操作:在尾指针后插入新节点,并更新尾指针
int EnQueue(CirLinkQueue *Q, DataType x) {
// 创建新节点
LNode *newNode = (LNode *)malloc(sizeof(LNode));
newNode->data = x;
// 新节点的next指向头节点(保持循环特性)
newNode->next = (*Q)->next;
// 原尾节点的next指向新节点
(*Q)->next = newNode;
// 更新尾指针为新节点
*Q = newNode;
return 1;
}
// 出队操作:删除头节点后的第一个节点(队头),并返回其值
int DelQueue(CirLinkQueue *Q, DataType *x) {
if (IsEmptyQueue(*Q)) {
return 0;
}
// 找到队头节点(头节点的next)
LNode *head = (*Q)->next;
LNode *front = head->next;
// 获取队头元素的值
*x = front->data;
// 更新头节点的next,跳过队头节点
head->next = front->next;
// 若删除的是最后一个节点,更新尾指针为头节点
if (front == *Q) {
*Q = head;
}
// 释放队头节点的内存
free(front);
return 1; // 出队成功
}
4.循环链表的操作集合(只设rear和quelen)
cpp
复制代码
int IsEmptyQueue(SeQueue *Q){
if(Q->quelen==0) return 1;
return 0;
}
int IsFullQueue(SeQueue *Q){
if(Q->quelen==MAXSIZE) return 1;
return 0;
}
int EnQueue(SeQueue *Q,ElemType x){
if(IsFullQueue(Q)) return 0;
Q->rear=(Q->rear+1)%MAXSIZE;
Q->elem[Q->rear]=x;
Q->quelen++;
return 1;
}
int DelQueue(SeQueue *Q,ElemType *x){
if(IsEmptyQueue(Q)) return 0;
int front=(Q->rear-Q->quelen+1+MAXSIZE)%MAXSIZE;
*x=Q->elem[front];
Q->quelen--;
return 1;
}
5.循环队列的操作集合(增设tag)
cpp
复制代码
SeqQueue * InitQueue(){
SeqQueue *Q=(SeqQueue *)malloc(sizeof(SeqQueue));
Q->rear=0,Q->front=0,Q->tag=0;
return Q;
}
int IsEmptyQueue(SeqQueue *Q){
if((Q->rear==Q->front)&&Q->tag==0) return 1;
return 0;
}
int IsFullQueue(SeqQueue *Q){
if((Q->rear==Q->front)&&Q->tag==1) return 1;
return 0;
}
int EnQueue(SeqQueue *Q,ElemType x){
if(IsFullQueue(Q)) return 0;
Q->rear=(Q->rear+1)%MAXSIZE;
Q->elem[Q->rear]=x;
Q->tag=1;
return 1;
}
int DelQueue(SeqQueue *Q,ElemType *x){
if(IsEmptyQueue(Q)) return 0;
Q->front=(Q->front+1)%MAXSIZE;
*x=Q->elem[Q->front];
Q->tag=0;
return 1;
}
六、树
1.二叉树中求度为2的结点的个数
cpp
复制代码
int Degree2(BiTree bt){
if(bt==NULL) return 0;
int sum=0;
if(bt->Lchild!=NULL&&bt->Rchild!=NULL)
sum++;
return sum+Degree2(bt->Lchild)+Degree2(bt->Rchild);
}
2.交换二叉树的左右子树
cpp
复制代码
void SwapLR(BiTree bt){
BiTree t;
if(bt==NULL) return ;
t=bt->Lchild;
bt->Lchild=bt->Rchild;
bt->Rchild=t;
SwapLR(bt->Lchild);
SwapLR(bt->Rchild);
}
3.二叉树的先序输出各结点及其层次
cpp
复制代码
void PreOrderLayer (BiTree bt, int lay){
if(bt==NULL) return ;
printf("(%c,%d)",bt->data,lay);
PreOrderLayer(bt->Lchild,lay+1);
PreOrderLayer(bt->Rchild,lay+1);
}
4.求树(或森林)的叶子结点数
cpp
复制代码
int NumOfLeaf(CSTree rt){
if(rt==NULL) return 0;
int count=0;
if(rt->FirstChild==NULL) count++;
return count+NumOfLeaf(rt->FirstChild)+NumOfLeaf(rt->NextSibling);
}
5. 求树(或森林)的高度
cpp
复制代码
int GetHeight (CSTree rt){
if(rt==NULL) return 0;
int child_h=1+GetHeight(rt->FirstChild);
int next_h=GetHeight(rt->NextSibling);
return child_h>next_h?child_h:next_h;
}