用C语言实现简单循环队列结构

用C实现简单循环队列结构 /* * 用C实现简单循环队列结构 * * 循环队列的类型定义如下: * typedef struct{ * valuetype data[MAXSIZE]; [>数据的存储区<] * int front, rear; [>队首队尾<] * int num; [>队列中元素的个数<] * }Circular_Queue; * 循环队列常用函数如下: * (1)Circular_Queue * Init_CirQueue(): 初始化队列 * (2)int In_CirQueue(Circular_Queue *q, valuetype x): 将元素x插入队列q的队尾,若成功返回1,否则返回0 * (3)int Out_CirQueue(Circular_Queue *q, valuetype *x): 取出队列q队首位置的元素,若成功返回1,否则返回0 */ /*程序代码:*/ #include <stdio.h> #include <malloc.h> #define MAXSIZE 100 typedef int valuetype; typedef struct{ valuetype data[MAXSIZE]; /*数据的存储区*/ int front, rear; /*队首队尾*/ int num; /*队列中元素的个数*/ }Circular_Queue; Circular_Queue * Init_CirQueue() { Circular_Queue *q = (Circular_Queue*)malloc(sizeof(Circular_Queue)); q->front = q->rear = MAXSIZE-1; q->num = 0; return q; } int In_CirQueue(Circular_Queue *q, valuetype x) { if(q->num == MAXSIZE) return 0; /*队满,不能入队*/ else { /*q->rear = (q->rear+1)%MAXSIZE;*/ q->data[q->rear] = x; q->rear = (q->rear+1)%MAXSIZE; q->num++; return 1; } } int Out_CirQueue(Circular_Queue *q, valuetype *x) { if(q->num == 0) return 0; /*队空*/ else{ *x = q->data[q->front]; q->front = (q->front+1)%MAXSIZE; q->num--; return 1; } } int main() { Circular_Queue *queue = Init_CirQueue(); int x=0; for(int i=0;i<10;++i) { if(!In_CirQueue(queue, i)) break; } while(Out_CirQueue(queue, &x)) printf("%d ",x); printf("\n"); return 0; }

2015年3月21日 · 1 分钟 · Jid

八皇后问题递归回溯算法实现

八皇后问题递归回溯算法实现 /* * 八皇后问题递归回溯算法实现 * * 八皇后问题或N皇后问题描述为: * 求解如何在N*N的棋盘上无冲突地排放N个皇后棋子。其中,皇后的移动方式规定为水平、竖直及45°斜线方向。因此,在任意一个皇后所在位置的水平、竖直和45°方向上都不能出现其他的皇后棋子。 * * 回溯法的基本思想是:在包含问题的所有解的解空间树中,按照深度优先搜索的策略,从根结点出发深度探索解空间树。当探索到某一个结点时,要先判断该结点是否包含问题的解,如果包含,就从该节点出发继续探索下去;如果该结点不包含问题的解,那就说明以该结点为根结点的子树一定不包含问题的最终解,因此要跳过对以该节点为根的子树的系统探索,逐层向其祖先结点回溯。这个过程又叫做解空间树的剪枝操作。 * * 八皇后问题可以有很多解法,其中之一是回溯法。 * 用回溯法求解八皇后问题,可以按列试探可能的解,一旦该列找不到任何可能的解那么就要向后回溯。 */ /*程序代码如下:*/ #include <stdio.h> #define NUM 8 /*棋盘用NUM*NUM的矩阵Q描述,其中,里面的元素如果是1表示可以放置皇后,如果为0表示不能放置皇后,另外,(i,j)表示矩阵的第(i,j)个元素*/ /*判断能否在(i,j)位置放置皇后*/ int isOK(int i, int j, int (*Q)[NUM]) { int s=0, t=0; for(s=i,t=0;t<NUM;++t) /*判断行*/ if(t!=j && Q[s][t]==1) return 0; for(s=0,t=j;s<NUM;++s) /*判断列*/ if(s!=i && Q[s][t]==1) return 0; for(s=i-1,t=j-1;s>=0&&t>=0;--s,--t) /*判断左上方*/ if(Q[s][t]==1) return 0; for(s=i+1,t=j-1;s<NUM&&t>=0;++s,--t) /*判断左下方*/ if(Q[s][t]==1) return 0; /* Thank @ewitt*/ /* 下面的东西没用 */ /* for(s=i-1,t=j+1;s>=0&&t<NUM;--s,++t) //判断右上方 * if(Q[s][t]==1) * return 0; * for(s=i+1,t=j+1;s<NUM&&t<NUM;++s,++t) //判断右下方 * if(Q[s][t]==1) * return 0; */ return 1; } void Queen(int j, int (*Q)[NUM]) { if(j==NUM) /*找到一个解*/ { for(int i=0;i<NUM;++i) { for(int k=0;k<NUM;++k) printf("%d ",Q[i][k]); printf("\n"); } printf("\n"); return; } else{ for(int i=0;i<NUM;++i) { if(isOK(i,j,Q)) /*如果可以*/ { Q[i][j]=1; Queen(j+1,Q); /*深度优先探索解空间树*/ Q[i][j]=0; } } } } /*test program*/ int main() { int Q[NUM][NUM]; int i=0, j=0; for(i=0;i<NUM;++i) for(j=0;j<NUM;++j) Q[i][j] = 0; /*初始化*/ Queen(0,Q); return 0; }

2015年3月20日 · 1 分钟 · Jid

用C语言实现简单链式队列结构

##用C语言实现简单链式队列结构 /* * 用链式结构实现的队列称为链队。根据队列的FIFO原则,为了操作上的方便,可以用带头指针font和尾指针rear的单链表来实现队列。链队结构描述: * typedef struct node * { * valuetype data; * struct node *next; * }QNode; [>链队结点的类型<] * typedef struct * { * QNode *front, *rear; * }LQueue; [>将头尾指针封装在一起的链队<] * * 设q是一个指向链队的指针,即LQueue *q. 各函数的功能如下: * (1)LQueue * Init_LQueue(): 创建并返回一个带头尾结点的空链队 * (2)int Empty_LQueue(LQueue *q): 判断链队是否为空 * (3)void In_LQueue(LQueue *q, valuetype x) : 将数据x压入链队q * (4)int Out_LQueue(LQueue *q, valuetype *x) : 弹出链队q的第一个元素x, 若成功则返回1否则返回0 * By Guv 2011.06.10 */ /*程序代码:*/ #include <stdio.h> #include <malloc.h> typedef int valuetype; typedef struct node { valuetype data; struct node *next; }QNode; typedef struct { QNode *front, *rear; }LQueue; LQueue * Init_LQueue() { LQueue *q; QNode *p; q = (LQueue*)malloc(sizeof(LQueue)); /*申请链队指针*/ p = (QNode*)malloc(sizeof(QNode)); /*申请头尾指针结点*/ p->next = NULL; q->front = q->rear = p; return q; } int Empty_LQueue(LQueue *q) { if(q->front != q->rear) return 0; else return 1; } void In_LQueue(LQueue *q, valuetype x) { QNode *p = (QNode *)malloc(sizeof(QNode)); /*申请新结点*/ p->data = x; p->next = NULL; q->rear->next = p; q->rear = p; } int Out_LQueue(LQueue *q, valuetype *x) { if(Empty_LQueue(q)) return 0; /*空链队*/ else{ QNode *p = q->front->next; *x = p->data; q->front->next = p->next; free(p); if (q->front->next == NULL) q->rear = q->front; return 1; } } int main() { LQueue *queue = Init_LQueue(); for (int i=0;i<10;++i) { In_LQueue(queue, i); } while(!Empty_LQueue(queue)) { int k=0; Out_LQueue(queue, &k); printf("%d ",k); } printf("\n"); return 0; }

2015年3月20日 · 2 分钟 · Jid

把数组的前k位逆置:递归算法和迭代算法

把数组的前k位逆置 /* * 逆置数组arr的前k位: * (1)递归实现 * (2)迭代实现 * PS.通常递归算法能解决一些不能直接解决的问题, * 但是递归算法通常要做出效率上的牺牲 * By Guv 2011.06.04 * */ #include <stdio.h> /*递归实现*/ void invert(int arr[], int k) { if(k>1){ invert(arr+1,k-2); int tmp = arr[0]; arr[0] = arr[k-1]; arr[k-1] = tmp; } } /*迭代*/ /* void invert(int arr[], int k) { int tmp=0, mid = k/2; if (k<2) return; for(int i=0;i<mid;++i){ tmp = arr[i]; arr[i] = arr[k-1-i]; arr[k-1-i] = tmp; } } */ /*testing*/ int main() { int array[] = {1,2,5,9,8,7,6,3,5,6,7,8,9,5,6,4,1,5,2,6,3,5}; int num = sizeof(array)/sizeof(int); printf("before inverted:"); for(int i=0;i<num;++i){ if (i%5==0) printf("\n"); printf("%d, ", array[i]); } invert(array, num); printf("\nafter inverted:"); for(int i=0;i<num;++i){ if (i%5==0) printf("\n"); printf("%d, ", array[i]); } }

2015年3月19日 · 1 分钟 · Jid

使用 Google Analytics 追踪 404 页面

为什么追踪 404 404 页面意味着用户访问了不存在的 URL。追踪这些请求可以: 发现损坏的内部链接 了解用户想找什么内容(可能值得补充) 找到哪些外部网站链到了你已删除的页面 实现方法 在 404 页面的 Google Analytics 追踪代码中,将页面路径改为包含请求 URL 的自定义路径: 新版 GA(gtag.js): <script> gtag('config', 'GA_MEASUREMENT_ID', { page_path: '/404?page=' + document.location.pathname + document.location.search + '&from=' + document.referrer }); </script> 旧版 GA(analytics.js): <script> ga('send', 'pageview', '/404?page=' + document.location.pathname + document.location.search + '&from=' + document.referrer); </script> 查看报告 在 Google Analytics 中查看 行为 → 网站内容 → 所有页面,搜索 /404,即可看到: 哪些 URL 触发了 404 来源页面(from 参数) 访问频率和趋势 根据这些信息修复损坏链接或补充缺失内容。 参考:月光博客

2015年3月19日 · 1 分钟 · Jid

用C语言实现简单的链式栈结构

C语言实现简单的链式栈结构 /* * 用链式存储结构实现的栈称为链栈。若链栈元素的数据类型为valuetype,以LinkStack记链栈结构,其类型定义为: * typedef struct node * { * valuetype data; * struct node * next; * } StackNode, *LinkStack; * * 由于栈的主要操作都是在栈顶进行的,因此把链表的头部作为栈顶。设top为栈顶指针,即:LinkStack top. * 下面为各函数的功能说明: * (1)LinkStack Init_LinkStack() : 建立并返回空的链栈 * (2)int Empty_LinkStack(LinkStack top) : 判断top所指链栈是否为空 * (3)LinkStack Push_LinkStack(LinkStack top, valuetype x) : 将数据x压入top所指的栈顶,并返回新栈指针 * (4)LinkStack Pop_LinkStack(LinkStack top, valuetype *x) : 弹出top所指链栈的栈顶元素x,返回新栈指针 * */ #include <stdio.h> #include <malloc.h> typedef int valuetype; typedef struct node { valuetype data; struct node * next; } StackNode, *LinkStack; LinkStack Init_LinkStack() { return NULL; } int Empty_LinkStack(LinkStack top) { if (top==NULL) return 1; else return 0; } LinkStack Push_LinkStack(LinkStack top, valuetype x) { StackNode *s = (StackNode *)malloc(sizeof(StackNode)); s->data = x; s->next = top; return s; } LinkStack Pop_LinkStack(LinkStack top, valuetype *x) { StackNode *p; if (top==NULL) return NULL; else { *x = top->data; p = top->next; free(top); return p; } } int main() { LinkStack linkstack = Init_LinkStack(); int i=0; int x=0; for (i=0;i<10;++i) { linkstack = Push_LinkStack(linkstack, i); } while(linkstack) { linkstack = Pop_LinkStack(linkstack, &x); printf("%d ",x); } printf("\n"); }

2015年3月18日 · 1 分钟 · Jid

cppman:在终端查看 C++ 文档的利器

简介 cppman 从 cplusplus.com 抓取 C++ 标准库文档,以 man page 格式在终端中展示。比 libstdc++ 文档更方便,是 C++ 程序员的效率工具。 安装(Ubuntu) # 1. 添加 PPA 源 sudo add-apt-repository ppa:aitjcize/manpages-cpp sudo apt-get update # 2. 安装 sudo apt-get install manpages-cpp # 3. 缓存文档数据(首次需要,耗时较长) cppman -c 使用 # 查询标准库组件 cppman cout cppman vector cppman string cppman iterator # 查看 STL 算法 cppman sort cppman find_if # 更新缓存 cppman -u 为什么推荐 直接按名称查询:不用记 std:: 前缀,cppman cout 即可 格式统一:和 man 命令一样的阅读体验 离线可用:缓存后无需联网

2015年3月17日 · 1 分钟 · Jid

C++ man pages 的使用方法

前提:已安装 C++ man pages,参见上篇。 问题 man cout 提示 No manual entry for cout,无法直接查询 C++ 标准库函数。 解决方法 C++ man pages 按命名空间和头文件组织,查询格式为: man 命名空间::头文件名 示例 # 查询 cout —— 属于 std 命名空间,定义在 iostream 中 man std::iostream # 打开后按 /cout 搜索 # 查询 slist —— 属于 __gnu_cxx 命名空间 man __gnu_cxx::slist # 查询 vector man std::vector 与 C 语言 man pages 的对比 操作 C 语言 C++ 查询 printf man 3 printf — 查询 cout — man std::iostream 后搜索 章节指定 man 2 open(系统调用) man std::vector 直接按函数名查 ✅ ❌ 需要知道所属头文件 注意:C++ man pages 由 Doxygen 生成,描述可能不如 C 的 man pages 详细。 ...

2015年3月16日 · 1 分钟 · Jid

Linux 安装 C++ man pages

本篇介绍在ubuntu上安装C++在线文档(man pages),下篇将介绍C++在线文档的使用。需要注意的一点是:在这里的方法有别于通常的 man func_name,因此需要单独说明,以免安装后也不知道怎么用。 另外,为了达到最好的使用效果,请首先把C的开发文档提前安装上吧,命令: sudo apt-get update sudo apt-get install manpages-dev glibc-doc 然后安装C++的开发文档,命令通常是 sudo apt-get install libstdc++6-4.4-doc 上面的4.4是gcc的版本,可以是4.2、4.3、4.4, 4.4是最新的。至于软件库中有无4.4,请参见下文的说明,使用命令查询: apt-cache search libstdc++|grep "doc" 以决定安装4.2、4.3或4.4 下面是英文原文: It’s so easy to search for any C related programming functions. All you need is to search the man pages. Take for example, if you want to know more about printf, simply type `$ man 2 printf` But that’s not the case with C++ functions. Every time, you have to go to the web for any doubts related to C++ functions. There are two ways by which you can search for documentation related to C++ functions. Man pages for C++ functions HTML documentation Both of the above are available from a single package. To install C++ documentation `$ sudo apt-get install libstdc++6-4.4-doc` This installs both the man pages and HTML documentation. The HTML documentation is found in the following path:file:///usr/share/doc/libstdc++6-4.4-doc/libstdc++/html/index.html If you are struggling to search C++ man pages, ReferHow to search C++ man pages Now there may be case that when you are referring this article the documentation 6.4.4 version is no longer available. In that case, follow the following steps `$ apt-cache search libstdc++|grep"doc"` libstdc++6-4.4-doc - The GNU Standard C++ Library v3 (documentation files)libstdc++6-4.1-doc - The GNU Standard C++ Library v3 (documentation files)libstdc++6-4.3-doc - The GNU Standard C++ Library v3 (documentation files) Search for the libstdc++ docs as shown above and install the version you want, preferably the latest ones (as shown above) `$ sudo apt-get install libstdc++6-4.4-doc`

2015年3月15日 · 2 分钟 · Jid

C 语言实现单向链表

实现一个简单的单向链表,包含头插法、逆序复制、遍历打印和释放操作。 代码 #include <stdio.h> #include <stdlib.h> typedef struct node { int val; struct node *next; } NODE; /* 头插法:在链表头部插入新节点 */ void first_insert(NODE **head, int v) { NODE *q = malloc(sizeof(NODE)); q->val = v; q->next = *head; *head = q; } /* 逆序复制链表,返回新链表头 */ NODE *reverse_copy(NODE *p) { NODE *new_list = NULL; for (; p != NULL; p = p->next) first_insert(&new_list, p->val); return new_list; } /* 遍历打印 */ void print_link(NODE *p) { for (; p != NULL; p = p->next) printf("%d ", p->val); printf("\n"); } /* 释放整个链表 */ void free_link(NODE *p) { while (p != NULL) { NODE *next = p->next; free(p); p = next; } } int main(void) { NODE *list1 = NULL, *list2; /* 构建链表:9 8 7 6 5 4 3 2 1(头插法导致逆序) */ for (int i = 1; i < 10; i++) first_insert(&list1, i); list2 = reverse_copy(list1); /* 1 2 3 4 5 6 7 8 9 */ print_link(list1); print_link(list2); free_link(list1); free_link(list2); return 0; } 关键点 头插法(first_insert):新节点插到链表头部,时间复杂度 O(1) 逆序复制:利用头插法的特性——正序遍历原链表、头插到新链表,自然得到逆序 释放链表:先保存 next 指针再 free 当前节点,避免访问已释放内存

2015年3月14日 · 1 分钟 · Jid