浏览次数: 八月 31st, 2010 / No Comments » / by 小黑
额,今天的是链队列~
命令行运行输出效果如下:
- 将10入队
- 将20入队
-
- 打印此队列:
- 10->20->NULL
-
- 将30入队
-
- 打印此队列:
- 10->20->30->NULL
-
- 弹出10
- 弹出20
-
- 打印此队列:
- 30->NULL
-
- 弹出30
-
- 打印此队列:
- NULL
-
- 将40入队
-
- 打印此队列:
- 40->NULL
下面是源码
- typedef int Elemtype;
-
- typedef struct LQNode
- {
- Elemtype data;
- struct LQNode *next;
- }LQNode,*LinkedQNode;
-
- typedef struct
- {
- LinkedQNode front,rear;
- }LQueue,*LinkedQueue;
-
-
- LinkedQueue LinkedQueueInit(void){
- LinkedQueue Q;
- LinkedQNode n;
- Q = (LinkedQueue) malloc(sizeof(LQueue));
- n = (LinkedQNode) malloc(sizeof(LQNode));
- n->next = NULL;
- Q->front = Q->rear = n;
- return Q;
- }
-
-
- void LinkedQueueDump(LinkedQueue q)
- {
- printf("\n打印此队列:\n");
- LinkedQNode tmp;
- tmp = q->front->next;
- while (tmp!=NULL){
- printf("%d->",tmp->data);
- tmp = tmp->next;
- }
- printf("NULL\n\n");
- return;
- }
-
- void LinkedQueueIn(LinkedQueue q,Elemtype data){
- LinkedQNode tmp = (LinkedQNode) malloc(sizeof(LQNode));
- tmp->data = data;
- tmp->next = NULL;
- q->rear->next = tmp;//原来的尾节点指向新节点
- q->rear = tmp;//指针指向刚加的节点
- printf("将%d入队\n",data);
- }
-
- Elemtype LinkedQueueOut(LinkedQueue q){
- //判断队列不为空
-
- if(q->front==q->rear){
- err("队列为空了!");
- }
- Elemtype x;
- LinkedQNode tmp = q->front->next;
- q->front->next = tmp->next;
- x = tmp->data;
- free(tmp);
- if(q->front->next==NULL){//因为入队的时候,rear增加,所以最后一个出队的时候,头指针指向NULL,需要把尾指针和头指针指向同一地址
- q->rear = q->front;
- }
- printf("弹出%d\n",x);
- return x;
- }
-
-
-
- int main(int argc, char **argv) {
- LinkedQueue q = LinkedQueueInit();
- LinkedQueueIn(q,10);
- LinkedQueueIn(q,20);
- LinkedQueueDump(q);
- LinkedQueueIn(q,30);
- LinkedQueueDump(q);
- LinkedQueueOut(q);
- LinkedQueueOut(q);
- LinkedQueueDump(q);
- LinkedQueueOut(q);
- LinkedQueueDump(q);
- LinkedQueueIn(q,40);
- LinkedQueueDump(q);
- return 0;
- }
Posted in: 算法研究
浏览次数: 八月 30th, 2010 / No Comments » / by 小黑
此次是队列~ FIFO~
-
- #define MAXSIZE 100
- #define MODCAL(x) x%100
-
-
- typedef struct {
- int data[MAXSIZE];
- int front,rear;
- } SeqQueue;
-
-
- SeqQueue SeqQueueInit(void){
- SeqQueue Q;
- Q.rear=Q.front=0;
- return Q;
- }
-
- int SeqQueueFull(SeqQueue *p){
- if(MODCAL(p->rear+1)==p->front) return 1;
- else return 0;
- }
-
- int SeqQueueEmpty(SeqQueue *p){
- if(p->rear==p->front) return 1;
- else return 0;
- }
-
- int SeqQueueOut(SeqQueue *p){
- if(SeqQueueEmpty( p )){
- err("队列空了!");
- }
- int x;
- p->front = MODCAL(p->front+1);
- x = p->data[p->front];
- printf("%d 出队了\n",x);
- return x;
- }
-
- void SeqQueueIn(SeqQueue *q,int data){
- if(SeqQueueFull(q)){
- err("队列满了!");
- }
- q->rear=MODCAL(q->rear+1);
- q->data[q->rear] = data;
- }
-
-
- void dump(SeqQueue *p){
- printf("当前队列情况:");
- int tmp = p->rear;
- while(p->front!=tmp){
- printf("<-%d",p->data[tmp]);
- tmp=(tmp-1)%MAXSIZE;
- }
- printf("\n");
- }
-
-
- int main(int argc, char **argv) {
- SeqQueue q = SeqQueueInit();
- dump(&q);
- SeqQueueIn(&q,10);
- SeqQueueIn(&q,20);
- dump(&q);
- SeqQueueOut(&q);
- dump(&q);
- return 0;
- }
运行后输出以下信息
- 当前队列情况:
- 当前队列情况:<-20<-10
- 10 出队了
- 当前队列情况:<-20
Posted in: 算法研究
浏览次数: 八月 26th, 2010 / 1 Comment » / by 小黑
汉诺塔问题~ 想了想,根据算法书籍完成
使用栈以及递归完成
是使用数组作为栈的数据区还是使用链作为栈的数据区,我认为这个是根据数据的变动频率作为参考依据,如果变动很频繁或有移动的操作,我认为应该考虑使用链,因为链的节点移动对数据产生的波动比较小,以下盘子在x,y,z柱子之间移动511次全部都是指针的计算,效率还不错~ 当然要自己释放和管理内存了~
- #define LINKNODEINIT() (LinkNode) malloc(sizeof(Node));
- #define PANZI 9 //盘子数量
-
- typedef struct Node{
- int data;
- struct Node *next;
- }Node, *LinkNode;
-
- int step = 0;
-
- LinkNode linkedStackInit(void){
- LinkNode l=LINKNODEINIT();
- if(l==NULL) err("malloc error!");
- l->next = NULL;
- return l;
- }
-
- void linkedStackInsert(LinkNode s,int data){
- LinkNode l = LINKNODEINIT();
- if(l==NULL) err("malloc error!");
- l->next = s->next;
- l->data = data;
- s->next = l;
- }
-
- void dump(LinkNode s){
- if(s->next!=NULL){
- s=s->next;
- while(s!=NULL){
- printf("%d\n",s->data);
- s=s->next;
- }
- }
- }
-
- void hanoiMove(LinkNode s,LinkNode t){
- //判断s柱是否为空
- if(s->next==NULL) err("被移动的柱子没有盘子!");
- else{
- LinkNode tmpS,tmpT,tmpSS;
-
- tmpSS = s->next->next;
- tmpS = s->next;
- tmpT = t->next;
-
- t->next = tmpS;
- tmpS->next = tmpT;
- s->next = tmpSS;
- step++;
- }
- }
-
- void hanoi(int n,LinkNode x,LinkNode y,LinkNode z){
- if(n==1){
- hanoiMove(x,z);
- }else{
- hanoi(n-1,x,z,y);
- hanoiMove(x,z);
- hanoi(n-1,y,x,z);
- }
- }
-
- int main(int argc, char **argv) {
- //初始化汉诺塔
- LinkNode x = linkedStackInit();
- LinkNode y = linkedStackInit();
- LinkNode z = linkedStackInit();
- int i;
- for(i=PANZI;i>0;i--){
- linkedStackInsert(x,i);
- }
- printf("x的盘子:\n");
- dump(x);
-
- hanoi(PANZI,x,y,z);
- printf("\n移动了%d次后\n\n",step);
-
- printf("x的盘子:\n");
- dump(x);
- printf("z的盘子:\n");
- dump(z);
-
- return 0;
- }
运行后结果如下:
- x的盘子:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-
- 移动了511次后
-
- x的盘子:
- z的盘子:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
Posted in: 算法研究
浏览次数: 八月 25th, 2010 / No Comments » / by 小黑
链栈其实就是单链表使用头插法~ 呵呵~
记得四则运算法则不?原来可以通过栈来完成的~
下面代码:
- typedef struct Node{
- int data;
- struct Node *next;
- }Node, *LinkNode;
-
- #define LINKNODEINIT() (LinkNode) malloc(sizeof(Node));
-
- LinkNode init(void){
- LinkNode l=LINKNODEINIT();
- if(l==NULL) err("malloc error!");
- l->next = NULL;
- return l;
- }
-
- void insert(LinkNode s,int data){
-
- LinkNode l = LINKNODEINIT();
- if(l==NULL) err("malloc error!");
- l->next = s->next;
- l->data = data;
- s->next = l;
- }
-
- int top(LinkNode s){
- if(s->next == NULL){
- return 0;
- }else{
- return s->next->data;
- }
- }
-
-
- int cal(int x,int y,int op){
- switch(op){
- case '+':return (x+y);
- case '-':return (x-y);
- case '*':return (x*y);
- case '/':return (x/y);
- default:return 0;
- }
- }
-
- int pop(LinkNode s){
- int x;
- if(s->next==NULL){
- err("link stack empty!");
- }
-
- x = s->next->data;
- LinkNode tmp = s->next;
- s->next = s->next->next;
- free(tmp);
- tmp = NULL;
- return x;
- }
-
- void dump(LinkNode s){
- s = s->next;
- while(s!=NULL){
- printf("%d\n",s->data);
- s = s->next;
- }
- }
-
- int precede(int i,int y){
- if(i=='#') return '<';
- else if(y=='#') return '>';
- else if(y=='(') return '<';
- else if(i=='('&&y==')') return '=';
- else if(i!='('&&y==')') return '>';
-
- if(y=='+'||y=='-')
- {
- if(i!='*'||i!='/') return '<';
- else return '>';
- }
-
- if(y=='*'||y=='/')
- {
- if(i!='*'||i!='/') return '<';
- else return '>';
- }
- }
-
-
- int main(int argc, char **argv) {
- LinkNode optr = init();
- insert(optr,'#');
- LinkNode opch = init();
- char *s = "2+3*(2+5*(6/1))#";
- int i=0;
- while((s[i]!='#')||top(optr)!='#'){
- if(s[i]>='0' && s[i]<='9'){
- printf("insert to opch:%d\n",s[i]-48);
- insert(opch,s[i]-48);
- i++;
- }else switch(precede(top(optr),s[i])){
- case '<':
- insert(optr,s[i]);
- printf("insert to optr:%c\n",s[i]);
- i++;
- break;
- case '=':
- pop(optr);
- printf("pop from optr:%c\n",s[i]);
- i++;
- break;
- case '>':
- insert(opch,cal(pop(opch),pop(opch),pop(optr)));
- }
- }
- //optr 出栈,一直到optr栈顶为#为止
- dump(opch);
- return 0;
- }
Posted in: 算法研究
浏览次数: 七月 30th, 2010 / 2 Comments » / by 小黑
RT,呵呵~ 经过几天的折磨后可以开始简单Object-c了~ 哈哈~

和web编程完全不一样,要非常小心内存泄露问题~
Posted in: object-c
浏览次数: 七月 16th, 2010 / 1 Comment » / by 小黑
作用是推荐好友的~ 范围是好友的好友(即2度)合并谁订阅过我的人~
- SELECT ma.uid,COUNT(1) AS p FROM match_ea ea LEFT JOIN match_ma ma ON ea.qid=ma.qid AND ea.aid=ma.aid
- INNER JOIN (
- SELECT DISTINCT uid FROM (
- SELECT DISTINCT uid FROM friend WHERE fuid IN (SELECT fuid FROM friend WHERE uid=121 AND STATUS=1)
- UNION SELECT uid FROM follow WHERE fuid=121
- ) b
- WHERE
- NOT EXISTS (SELECT NULL FROM friend WHERE uid=121 AND fuid=b.uid AND STATUS=1)
- ) c ON c.uid=ma.uid
- WHERE ea.uid=121
- GROUP BY uid ORDER BY p DESC LIMIT 10
此SQL有性能问题,呵呵~ 好友人数太多或订阅我的人数太多就会出现问题的~ 慎用,目前自己项目的SNS已经更新了更高效的作法~
Posted in: mysql
浏览次数: 六月 23rd, 2010 / No Comments » / by 小黑
最近在执行一个大型运算,数据库记录大约6000w, 使用其中200w对于mango进行测试, 但性能几乎让我大跌眼镜…
准备给mango填充数据
- set_time_limit(0);
- $m = new Mongo('localhost:27017');
- $collection = $m->selectDB('test')->selectCollection('match');
- $collection->ensureIndex(array("uid"=>1),array("unique"=>true));
- $person = NULL;
- $i=$j=1;
- $answer=array();
- for($i=1;$i<=1000000;$i++){
- $answer=array();
- for($j=1;$j<=20;$j++){
- $answer[]=mt_rand(1,5);
- }
- $person = array("uid"=>$i,"answer"=>implode("",$answer));
- $collection->insert($person);
- }
使用mango进行map/reduce进行运算
- m = function () {
- var i = this.answer;
- var n = 0;
- var s = 0;
- for (n; n < i; n++) {
- if (this.answer[n] == matchs[n]) {
- s++;
- }
- }
- emit(this.uid,s);
- }
- r = function(k,vals) {
- var sum=0;
- for(var i in vals) sum += parseInt(vals[i]);
- return sum;
- }
- res = db.match.mapReduce(m,r,{scope:{matchs:"21453214254123145213"}});
- //这里几乎卡死,1个CPU四核,其中1个核跑满,可见mango的map/reduce真的是单进程的...
还是改用mysql靠谱,对数据进行分表后,同样使用map/reduce取数据,大约能在1s内准确完成计算,这里不给出mysql的解决方案了哈~ 就是感叹下mango没有那么牛X的性能…
Posted in: php, 项目经验
浏览次数: 六月 3rd, 2010 / No Comments » / by 小黑
最近通过观察引潜网的流量,发现一个很有规律的事情~
就是周四的流量都较少,为啥会这么有趣呢?
想了想,可能大家周一到周三上班都没怎么效率,到周四发现工作还有很多没做完,就周四的工作效率非常高,到周五的时候因为快要放假心都不知道飞那里去了…
所以大家的周四的工作效率是最高的~ 要把握好周四哦~ 哈哈哈~
Posted in: 心路历程
浏览次数: 五月 21st, 2010 / No Comments » / by 小黑
先取模运算得出真实要旋转的次数,如果旋转次数比向量长度要大,会有边界问题~
然后把向量分成两部分进行翻转 向量X分成两部分为 ab 旋转的意思就是要把 ab 变成 ba , 先把a翻转成 r(a) 再翻转b成为r(b) 在把整个进行翻转 r(r(a)r(b)) 就成为了ba
- #include <stdio.h>
- char str[9] = "abcdefgh\0";
- void reverse(int act,int end){
- int tmp;
- for (;act<end;act++,end--){
- tmp = str[act];
- str[act]=str[end];
- str[end]=tmp;
- }
- }
-
- int main(void){
- int i=3;//左旋转次数
- int n = 8;//长度
-
- i=i%n;
-
- reverse(0,i-1);
- reverse(i,n-1);
- reverse(0,n-1);
- printf("%s\n",str);
- return 0;
- }
Posted in: 算法研究
浏览次数: 五月 1st, 2010 / No Comments » / by 小黑
在写多进程或多线程程序的时候要特别注意这个问题,如果调用exit可能会冲洗所有标准I/O流,并有可能关闭标准I/O流
下面是例子
- int main(int argc, char **argv) {
- int var;
- pid_t pid;
-
- var=8;
- printf("before fork\n");
-
- if((pid=vfork())<0){
- err_sys("fork error!");
- }else if(pid==0){//子进程
- glob++;
- var++;
- exit(0);//错误的使用
- _exit(0);//应该这样调用
- }
- printf("pid=%d ,glob=%d, var=%d\n",getpid(),glob,var);
- return 0;
- }
在某些系统上面编译运行后会发现没有任何输出,而上面的程序我只是让子进程退出,但是父进程为什么也不见有输出呢?原来exit关闭了标准输出,这个时候printf的返回值是”-1″…就是输出不成功!现在大家明白了吧~ 正确的应该调用 _exit(0);
Posted in: c/c++