C语言 翁凯老师 数据结构 链表学习(2)

遍历list,将链表里的数据输出

#include<stdio.h>
#include<stdlib.h>
#include"node.h"
/* typedef struct _node
{
    int value;
    struct  _node *next;
} Node; */
typedef struct _list
{
    Node* head;
    Node* tail;//永远指向最后一个节点
}List;
void * add(List *plist,int number);// 如果是void add 函数的话就要使用全局变量Node*head 但是,最好不要用全局变量,全局变量是有害的,程序只会是一次性的,只能对这一个链表有作用
void print(List *pList);/* 将链表遍历输出的子函数 */
int main()
{
    List list;
    list.head = list.tail = NULL;
    int number;
    do{
        scanf("%d",&number);
        if(number != 1){
            add(&list,number);
            // head = add(head,number);
        }
    }while (number != -1);
    printf(&list);
    return 0;
}

void * add(List *plist,int number)
{
    //add to linked-list
    Node *p = (Node*)malloc(sizeof(Node));
    p->value = number;
    p->next = NULL;
    //find the last
    Node *last = plist->tail;
    if(last){
        /* while (last->next){//遍历到last->next=NULL为止,保证数据存储在链表的最后一位
            last = last->next;
        }
        // attach */
        last->next = p;
        plist->tail = p;/* 如果前面是plist->head则没有该行 */
    }else{
        plist->head = p;
        plist->tail = p;/* 如果前面是plist->head则没有该行 */
    }
    // return head;
}
/*这就是将链表遍历输出的子函数*/
void print(List *pList)
{
	Node *p;
	for(p = pList->head; p ; p = p->next)//结束的条件是p不存在 //这就是链表的遍历,将链表里存储的东西从头输出到尾。 
	{
		printf("%d\t",p->value);
	}
    printf("\n");
} 

对链表内部数据进行查找:输入一个数据,查找链表内有无此数据

#include<stdio.h>
#include<stdlib.h>
#include"node.h"
/* typedef struct _node
{
    int value;
    struct  _node *next;
} Node; */
typedef struct _list
{
    Node* head;
    Node* tail;//永远指向最后一个节点
}List;
void * add(List *plist,int number);// 如果是void add 函数的话就要使用全局变量Node*head 但是,最好不要用全局变量,全局变量是有害的,程序只会是一次性的,只能对这一个链表有作用
void print(List *pList);/* 将链表遍历输出的子函数 */
int main()
{
    List list;
    list.head = list.tail = NULL;
    int number;
    do{
        scanf("%d",&number);
        if(number != 1){
            add(&list,number);
            // head = add(head,number);
        }
    }while (number != -1);
    
    printf(&list);

    //链表的查找
    scanf("%d",&number);
    Node *p;
    int isFound = 0;
    for(p = list.head; p ;p->next){
        if(p->value == number){
            printf("find it\n");
            isFound = 1;
            break;
        }
    }
    if( !isFound ){
        printf("can't find it");
    }

    return 0;
}

void * add(List *plist,int number)
{
    //add to linked-list
    Node *p = (Node*)malloc(sizeof(Node));
    p->value = number;
    p->next = NULL;
    //find the last
    Node *last = plist->tail;
    if(last){
        /* while (last->next){//遍历到last->next=NULL为止,保证数据存储在链表的最后一位
            last = last->next;
        }
        // attach */
        last->next = p;
        plist->tail = p;/* 如果前面是plist->head则没有该行 */
    }else{
        plist->head = p;
        plist->tail = p;/* 如果前面是plist->head则没有该行 */
    }
    // return head;
}
/*这就是将链表遍历输出的子函数*/
void print(List *pList)
{
	Node *p;
	for(p = pList->head; p ; p = p->next)//结束的条件是p不存在 //这就是链表的遍历,将链表里存储的东西从头输出到尾。 
	{
		printf("%d\t",p->value);
	}
    printf("\n");
} 

也可以将scanf放在主函数外,封装为另外一个搜索函数

8、删除链表中所储存的一个数。(注意这个程序所以只会删除搜索到的第一个数)

#include<stdio.h>
#include<stdlib.h>
#include"node.h"
/* typedef struct _node
{
    int value;
    struct  _node *next;
} Node; */
typedef struct _list
{
    Node* head;
    Node* tail;//永远指向最后一个节点
}List;
void * add(List *plist,int number);// 如果是void add 函数的话就要使用全局变量Node*head 但是,最好不要用全局变量,全局变量是有害的,程序只会是一次性的,只能对这一个链表有作用
void print(List *pList);/* 将链表遍历输出的子函数 */
int main()
{
    List list;
    list.head = list.tail = NULL;
    int number;
    do{
        scanf("%d",&number);
        if(number != 1){
            add(&list,number);
            // head = add(head,number);
        }
    }while (number != -1);

    printf(&list);

    //链表的查找
    scanf("%d",&number);
    Node *p;
    int isFound = 0;
    for(p = list.head; p ;p->next){
        if(p->value == number){
            printf("find it\n");
            isFound = 1;
            break;
        }
    }
    if( !isFound ){
        printf("can't find it\n");
    }

    Node *q;
    for(q = NULL,p = list.head; p ;q=p,p->next){
        if(p->value == number){
            if( q )
            {
                q->next = p->next;
            }else{
                list.head = p->next;
            }
            free(p);
            break;
        }
    }

    return 0;
}

void * add(List *plist,int number)
{
    //add to linked-list
    Node *p = (Node*)malloc(sizeof(Node));
    p->value = number;
    p->next = NULL;
    //find the last
    Node *last = plist->tail;
    if(last){
        /* while (last->next){//遍历到last->next=NULL为止,保证数据存储在链表的最后一位
            last = last->next;
        }
        // attach */
        last->next = p;
        plist->tail = p;/* 如果前面是plist->head则没有该行 */
    }else{
        plist->head = p;
        plist->tail = p;/* 如果前面是plist->head则没有该行 */
    }
    // return head;
}
/*这就是将链表遍历输出的子函数*/
void print(List *pList)
{
	Node *p;
	for(p = pList->head; p ; p = p->next)//结束的条件是p不存在 //这就是链表的遍历,将链表里存储的东西从头输出到尾。 
	{
		printf("%d\t",p->value);
	}
    printf("\n");
} 

若将其封装为查找和删除函数:

#include<stdio.h>
#include<stdlib.h>
#include"node.h"
/* typedef struct _node
{
    int value;
    struct  _node *next;
} Node; */
typedef struct _list
{
    Node* head;
    Node* tail;//永远指向最后一个节点
}List;
void * add(List *plist,int number);// 如果是void add 函数的话就要使用全局变量Node*head 但是,最好不要用全局变量,全局变量是有害的,程序只会是一次性的,只能对这一个链表有作用
void print(List *pList);/* 将链表遍历输出的子函数 */
int main()
{
    List list;
    list.head = list.tail = NULL;
    int number;
    do{
        scanf("%d",&number);
        if(number != 1){
            add(&list,number);
            // head = add(head,number);
        }
    }while (number != -1);

    printf(&list);

    found(&list);//链表的查找

    delete(&list);//链表的删除
    return 0;
}

void * add(List *plist,int number)
{
    //add to linked-list
    Node *p = (Node*)malloc(sizeof(Node));
    p->value = number;
    p->next = NULL;
    //find the last
    Node *last = plist->tail;
    if(last){
        /* while (last->next){//遍历到last->next=NULL为止,保证数据存储在链表的最后一位
            last = last->next;
        }
        // attach */
        last->next = p;
        plist->tail = p;/* 如果前面是plist->head则没有该行 */
    }else{
        plist->head = p;
        plist->tail = p;/* 如果前面是plist->head则没有该行 */
    }
    // return head;
}
/*这就是将链表遍历输出的子函数*/
void print(List *pList)
{
	Node *p;
	for(p = pList->head; p ; p = p->next)//结束的条件是p不存在 //这就是链表的遍历,将链表里存储的东西从头输出到尾。 
	{
		printf("%d\t",p->value);
	}
    printf("\n");
} 

void found(List *flist){
    int number = 0;
    scanf("%d",&number);
    Node *p;
    int isFound = 0;
    for(p = flist->head; p ;p->next){
        if(p->value == number){
            printf("find it\n");
            isFound = 1;
            break;
        }
    }
    if( !isFound ){
        printf("can't find it\n");
    }

}

void delete(List *flist)
{
    int number;
    scanf("%d",&number);
    Node *p,*q;
    for(q = NULL,p = flist->head;p;q=p,p=p->next){
        if(p->value == number){
            if(q){//保证q是可操作的而不是NULL,如果没有这个if,当所要删除的数是在第一个位置时,将会出现错误。 
                q->next = p->next;
            }else{
                flist->head = p->next;
            }
            free(p);
            break;
        }
    }
}

缺点是无法在删除之后输出链表,需要重新输出一下

链表的释放和清除

开辟了一片存储链表的空间,在最后要把这片空间给释放掉

#include<stdio.h>
#include<stdlib.h>
#include"node.h"
/* typedef struct _node
{
    int value;
    struct  _node *next;
} Node; */
typedef struct _list
{
    Node* head;
    Node* tail;//永远指向最后一个节点
}List;
void * add(List *plist,int number);// 如果是void add 函数的话就要使用全局变量Node*head 但是,最好不要用全局变量,全局变量是有害的,程序只会是一次性的,只能对这一个链表有作用
void print(List *pList);/* 将链表遍历输出的子函数 */
void found(List *flist);/* 链表元素的查找子函数 */
void delete(List *flist);/* 链表元素的删除子函数 */
void Free(List *flist);
int main()
{
    List list;
    list.head = list.tail = NULL;
    int number;
    do{
        scanf("%d",&number);
        if(number != 1){
            add(&list,number);
            // head = add(head,number);
        }
    }while (number != -1);

    print(&list);//将链表遍历输出

    found(&list);//链表的查找

    delete(&list);//链表元素的删除

    Free(&list);

    return 0;
}

void * add(List *plist,int number)
{
    //add to linked-list
    Node *p = (Node*)malloc(sizeof(Node));
    p->value = number;
    p->next = NULL;
    //find the last
    Node *last = plist->tail;
    if(last){
        /* while (last->next){//遍历到last->next=NULL为止,保证数据存储在链表的最后一位
            last = last->next;
        }
        // attach */
        last->next = p;
        plist->tail = p;/* 如果前面是plist->head则没有该行 */
    }else{
        plist->head = p;
        plist->tail = p;/* 如果前面是plist->head则没有该行 */
    }
    // return head;
}
/*这就是将链表遍历输出的子函数*/
void print(List *pList)
{
	Node *p;
	for(p = pList->head; p ; p = p->next)//结束的条件是p不存在 //这就是链表的遍历,将链表里存储的东西从头输出到尾。 
	{
		printf("%d\t",p->value);
	}
    printf("\n");
} 

void found(List *flist){
    int number = 0;
    scanf("%d",&number);
    Node *p;
    int isFound = 0;
    for(p = flist->head; p ;p->next){
        if(p->value == number){
            printf("find it\n");
            isFound = 1;
            break;
        }
    }
    if( !isFound ){
        printf("can't find it\n");
    }

}

void delete(List *flist)
{
    int number;
    scanf("%d",&number);
    Node *p,*q;
    for(q = NULL,p = flist->head;p;q=p,p=p->next){
        if(p->value == number){
            if(q){//保证q是可操作的而不是NULL,如果没有这个if,当所要删除的数是在第一个位置时,将会出现错误。 
                q->next = p->next;
            }else{
                flist->head = p->next;
            }
            free(p);
            break;
        }
    }
}

void Free(List *flist){
    Node *p,*q;
    for(p = flist->head; p;p = q){
        q = p->next;
        free(p);
    }
}

即上述的Free函数,也可以直接卸载主函数的最后部分。

Tic Tac Toe,也称为井字棋,是一个经典的两人对战策略游戏,玩家轮流在3x3的网格上放置他们的标记(通常是X和O)。在C语言中,翁凯版本可能会涉及到二维数组、循环控制、条件判断以及用户输入处理。 以下是创建一个简单的Tic Tac Toe游戏的基本步骤: 1. 定义一个3x3的二维字符数组,代表游戏板。 2. 创建一个函数`drawBoard()`来显示当前的游戏状态。 3. `playGame()`函数负责游戏的主要流程,包括接收玩家输入,更新游戏板,并检查是否获胜或平局。 4. 使用嵌套循环遍历游戏板,让两个玩家交替操作。 5. 添加条件判断来检测胜利(行、列、对角线上的三个同色格子),并提示赢家。 6. 如果没有赢家并且所有位置都被填满,判定为平局。 下面是一个非常简化的C语言Tic Tac Toe游戏示例(仅包含核心部分,不包含完整的源码): ```c #include <stdio.h> #define SIZE 3 // 检查某一行/列/对角线上是否有连续的符号 int checkWin(char board[SIZE][SIZE], char symbol) { for (int i = 0; i < SIZE; ++i) { if (board[i][0] == symbol && board[i][1] == symbol && board[i][2] == symbol) return 1; if (board[0][i] == symbol && board[1][i] == symbol && board[2][i] == symbol) return 1; if (board[0][0] == symbol && board[1][1] == symbol && board[2][2] == symbol) return 1; if (board[0][2] == symbol && board[1][1] == symbol && board[2][0] == symbol) return 1; } return 0; } void drawBoard(char board[SIZE][SIZE]) { // 打印游戏板 //... } int main() { char board[SIZE][SIZE] = { {' ' } }; int player = 'X'; while (true) { drawBoard(board); printf("Player %c's turn: ", player); int row, col; scanf("%d%d", &row, &col); // 输入坐标 if (board[row][col] != ' ') continue; board[row][col] = player; if (checkWin(board, player)) { printf("Player %c wins!\n", player); break; } // 切换玩家 player = (player == 'X') ? 'O' : 'X'; } return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

某石油中专在读坐牢2021级本科生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值