数据结构引入
线性表
线性表是包含若干数据元素的一个线性序列
记为: L=(a0, … ai-1, ai, ai+1 … an-1)
线性表的特征:
- 对非空表,a0是表头,无前驱;
- an-1是表尾,无后继;
- 其它的每个元素ai有且仅有一个直接前驱ai-1和一个直接后继ai+1
顺序表
线性表按照连续内存空间顺序存储就是顺序表。
linu文件结构:
数据结构:
1 /*
2 typedef int data_t;
3 #define N 128
4 struct sqlist_t{
5 data_t data[N];
6 int last;
7 };
8 typedef struct sqlist_t sqlist;
9 typedef struct sqlist_t* sqlink;
10 */
11
12 typedef int data_t;
13 #define N 128
14 typedef struct{
15 data_t data[N];
16 int last;
17 }sqlist,*sqlink;
gcc编译:
预处理 编译 汇编 链接
gcc -c sqlist.c -o sqligccst.o
gcc -c test.c -o test.o
gcc sqlist.o test.o -o test
也可以:
gcc -c *.c -o test
**删除中间文件:rm **.o test
sqlist.h文件
1 /*
2 typedef int data_t;
3 #define N 128
4 struct sqlist_t{
5 data_t data[N];
6 int last;
7 };
8 typedef struct sqlist_t sqlist;
9 typedef struct sqlist_t* sqlink;
10 */
11
12 typedef int data_t;
13 #define N 128
14 typedef struct{
15 data_t data[N];
16 int last;
17 }sqlist,*sqlink;
18
19 sqlink list_create();
20 int list_clear(sqlink L);
21 int lsit_empty(sqlink L);
22 int list_length(sqlink L);
23 int list_locate(sqlink L,data_t value);
24 int list_insert(sqlink L,data_t value,int pos);
25
26 int list_free(sqlink L);
27 int list_show(sqlink L);
28
29 int list_delete(sqlink L,int pos);
30 int list_merge(sqlink L1,sqlink L2);
31 int list_purge(sqlink L);
~
sqlist.c文件
1 #include<stdio.h>
2 #include<string.h>
3 #include<stdlib.h>
4 #include "sqlist.h"
5
6 sqlink list_create(){
7 //malloc
8 sqlink L;
9 L=(sqlink)malloc(sizeof(sqlist));
10 if(L==NULL)return NULL;
11 //initationize
12 memset(L,0,sizeof(sqlist));
13 L->last=-1;
14 return L;
15 }
16 /*
17 *
18 *@ret 0-success -1-failed
19 **/
20 int list_clear(sqlink L){
21 if(L==NULL)return -1;
22 memset(L,0,sizeof(sqlist));
23 L->last=-1;
24
25 return 0;
26 }
27 /*
28 *@brief Is list empty?
29 *@ret 1-empty -0-not empty -1-error
30 **/
31 int lsit_empty(sqlink L){
32 if(L==NULL)return -1;
33 if(L->last!=-1)return 1;
34 else
35 return 0;
36 }
37
38 /*
39 *@brief calculate list length
40 *@ret list length
41 **/
42 int list_length(sqlink L){
43 if(L==NULL)return -1;
44 else
45 return (L->last+1);
46 }
47
48 /*
49 *@brief is value into list?
50 *@ret i-value location -1-not into list
51 **/
52 int list_locate(sqlink L,data_t value){
53 int i;
54 for(int i=0;i<=L->last;i++){
55 if(value==L->data[i])return i;
56 }
57
58 return -1;
59 }
60 /*
61 *@brief value insert into list
62 *@ret 0-success -1-failed
63 **/
64 int list_insert(sqlink L,data_t value,int pos){
65 //cheeck full
66 if(L->last+1>=N){
67 printf("list is full\n");
68 return -1;
69 }
70 //check parament pos [0,last]
71 if(pos<0 || pos >L->last+1){
72 printf("pos is invalid\n");
73 return -1;
74 }
75 //move
76 int i;
77 for(i=L->last;i>=pos;i--){
78 L->data[i+1]=L->data[i];
79 }
80 //update last
81 L->data[pos]=value;
82 L->last++;
83
84 return 0;
85 }
86 /*
87 *@brief free list
88 *@ret 1-success -1-failed
89 **/
90 int list_free(sqlink L){
91 if(L==NULL)return -1;
92 free(L);
93 L=NULL;
94 return 1;
95 }
96 /*
97 *@brief print list data
98 *@ret 1-success -1-failed
99 **/
100 int list_show(sqlink L){
101 if(L==NULL)return -1;
102 int i;
103 for(int i=0;i<=L->last;i++){
104 printf("%d ",L->data[i]);
105 }
106 puts("");
107 return 1;
108
109 }
110 int list_delete(sqlink L,int pos){
111 //check parament
112 if(L==NULL)return -1;
113 //check pos [0,last]
114 if(pos<0 || pos>L->last){
115 printf("pos is invalid\n");
116 return -1;
117 }
118
119 //move
120 int i;
121 for(i=pos;i<L->last;i++){
122 L->data[i]=L->data[i+1];
123 }
124 //update
125 L->last--;
126 return 1;
127 }
128 int list_merge(sqlink L1,sqlink L2){
129 int i=0;
130 int ret;
131 while(i<=L2->last){
132 ret=list_locate(L1,L2->data[i]);
133 if(ret==-1){
34 if(list_insert(L1,L2->data[i],L1->last+1)==-1)
135 return -1;
136 }
137 i++;
138 }
139 return 0;
140 }
141 int list_purge(sqlink L){
142
143 int i=1,j;
144
145 while(i<=L->last){
146 j=i-1;
147 while(j>=0){
148 if(L->data[j]==L->data[i]){
149 list_delete(L,i);
150 break;
151 }else j--;
152 }
153 if(j<0)i++;
154 }
155 return 0;
156 }
notes:顺序表适用于查找用的较多,删除增加比较少的场景,比如图书馆管理系统。
单链表
单链表的操作主要是要找到他的前驱节点
结构:
结点的data域存放数据元素ai,而next域是一个指针,指向ai的直接后继ai+1所在的结点。
linklist.h
1 typedef int data_t;
2
3 typedef struct node{
4 data_t data;
5 struct node* next;
6 }listnode,*linklist;
7
8 linklist list_creat();
9 int list_tail_insert(linklist H,data_t value);
10 int list_show(linklist H);
11
12 linklist list_get(linklist H,int pos);
13 int list_insert(linklist H,data_t value,int pos);
14
15 int list_delete(linklist H,int pos);
16 linklist list_free(linklist H);
linklist.c
1 #include<stdio.h>
2 #include "linklist.h"
3 #include<stdlib.h>
4 #include<string.h>
5
6
7 linklist list_creat(){
8 linklist H=(linklist)malloc(sizeof(listnode));
9
10 if(H==NULL){
11 puts("create failed");
12 return H;
13 }
14
15 H->data=0;
16 H->next=NULL;
17 return H;
18 }
19
20 int list_tail_insert(linklist H,data_t value){
21 linklist q;
22 linklist p;
23 if(H==NULL){
24 printf("head is NULL\n");
25 return -1;
26 }
27 //create new node
28 if((p=(linklist)malloc(sizeof(listnode)))==NULL){
29 printf("malloc failed\n");
30 return -1;
31 }
32 p->data=value;
33 p->next=NULL;
34 //find tail node
35 q=H;
36 while(q->next!=NULL){
37 q=q->next;
38 }
39 //insert node
40 q->next=p;
41
42 return 0;
43 }
44
45 int list_show(linklist H){
46 linklist p;
47 if(H==NULL){
48 printf("head is NULL\n");
49 return -1;
50 }
51 p=H->next;//p=H;
52 while(p!=NULL){//while(p->next!=NULL)
53 printf("%d ",p->data);//printf("%d ",p->next->data);
54 p=p->next;
55 }
56 puts("");
57 return 0;
58 }
59
60 linklist list_get(linklist H,int pos){
61 if(H==NULL)return NULL;
62 int i=-1;//head node
63 //create new node
64 linklist p;
65 p=H;
66 //calculate loop times
67 while(i<pos){
68 p=p->next;
69 if(p==NULL){//deal special things=
70 printf("pos is invalid\n");
71 return NULL;
72 }
73 i++;
74 }
75 return p;
76 }
77 int list_insert(linklist H,data_t value,int pos){
78 if(H==NULL)return -1;
79
80 //get locate node
81 linklist p=list_get(H,pos-1);
82 if(p==NULL)return -1;
83
84 //create new node
85 linklist q;
86 if((q=(linklist)malloc(sizeof(listnode)))==NULL){
87 printf("create node failed\n");
88 return -1;
89 }
90 q->data=value;
91 q->next=NULL;
92
93 //insert node
94 q->next=p->next;
95 p->next=q;
96
97 return 0;
98 }
99
int list_delete(linklist H,int pos){
101 //check parament
102 if(H==NULL){
103 printf("H is NULL\n");
104 return -1;
105 }
106
107 //find node before pos
108 linklist p;
109 p=list_get(H,pos-1);
110 if(p==NULL || p->next==NULL){
111 printf("pos is invalied\n");
112 return -1;
113 }
114 //create new node to save delete node message
115 linklist q=p->next;
116 p->next=q->next;
117 printf("free %d\n",q->data);
118 free(q);
119 q=NULL;
120 return 0;
121 }
122 linklist list_free(linklist H){
123 if(H==NULL){
124 printf("H is NULL\n");
125 return NULL;
126 }
127
128 linklist p;
129 p=H;
130 printf("free:");
131 while(H!=NULL){
132 H=H->next;
133 printf("%d ",p->data);
134 free(p);
135 p=H;
136 }
137 puts("");
138 return NULL;
139 }
链表复杂操作操作
单链表反转
算法思路:
1、参数是否合法(H==NULL)?
2、初始状态(P=H->next->next,H->next->next=NULL,q=p)
3、具体算法实现(头插法):指针P按照顺序遍历H中的每一个节点,然后把这个节点插入到新链表的前面,实现翻转
q=p;
p=p->next;
q->next=H->next;
H->next=q;
4、返回值
141 int list_reverse(linklist H){
142
143 if(H==NULL){
144 printf("H is NULL\n");
145 return -1;
146 }
147
148 if(H->next==NULL || H->next->next==NULL)return 0;
149
150 //采用头插法实现链表反转
151 linklist p=H->next->next;
152 H->next->next=NULL;
153 /*
154 while(p!=NULL){
155 list_insert(H,p->data,0);
156 p=p->next;
157 }
158 */
159 //底层原理
160 linklist q;
161 while(p!=NULL){
162 q=p;
163 p=p->next;//顺序不能变
164
165 q->next=H->next;
166 H->next=q;
167
168 }
169
170 return 0;
171 }
单链表两个相邻节点之和最大值,第一个节点地址,以及最大值
算法思路:
1.判断参数是否合法:H 是空节点 链表只有1个或者两个节点,直接返回
2.判断特殊情况
3.具体算法实现:
变量存储:p,q存储相邻两个节点,sum存储两个节点最大值,r节点存储结果
初始状态:
p=H->next;
q=H->next->next;
r=p;
if((p->data+q->data)>sum) sum=p->data+q->data;r=p;
循环:
while(p->next!=NULL){
p=p->netx;
q=q->next;
}
4.返回值
172 linklist list_adjmax(linklist H,int* value){
173 if(H==NULL || H->next==NULL)return NULL;
174 if(H->next->next==NULL || H->next->next->next==NULL)return H->next;
175 /*
176 linklist p=H->next;
177 int max=p->data+p->next->data;
178 linklist result=p;
179 while(p->next!=NULL){
180 if((p->data+p->next->data)>max){
181 max=p->data+p->next->data;
182 result=p;
183 }
184 p=p->next;
185 }*/
186
187 linklist p,q;
188 p=H->next;
189 q=H->next->next;
190 int sum=p->data+q->data;
191 linklist r=H->next;
192 while(q->next!=NULL)
193 {
194 p=p->next;
195 q=q->next;
196 if((p->data +q->data)>sum){
197 sum=p->data+q->data;
198 r=p;
199 }
200 }
201 *value=sum;
202 return r;
203 }
两个有序链表合并
两个linklist指针遍历两个链表元素,利用linklist r指向一个新链表,r=H1,H1只有一个头结点
循环
对比p,q元素大小,小的插入新链表r,p或者q指向下一个元素,r也指向插入节点
算法思路:
1.检查参数H1NULL || H2NULL
2.特殊情况考虑
3.变量确定
两个linklist p,q遍历两个链表节,linklist r新链表
4.初始状态确定
p=H1->next
q=H2->next
r=H1
H1->next=NULL
H2->next=NULL
5.具体算法实现
while(p && q){
if(p->data <=q->data){
r->next=p;//r的next指向
p=p->next;//p就可以放心的指向下一个元素
r=r->next;//然后r就可以指向当前插入元素
r->next=NULL;//置0:
}
}
6.参数返回
204 int list_merge(linklist H1,linklist H2){
205 if(H1==NULL || H2==NULL)return -1;
206
207 linklist p=H1->next;
208 linklist q=H2->next;
209 linklist r=H1;
210 H1->next=NULL;
211 H2->next=NULL;
212
213 while(p!=NULL && q!=NULL){
214 if(p->data<=p->data){
215 r->next=p;
216 p=p->next;
217 r=r->next;
218 r->next=NULL;
219 }else{
220 r->next=q;
221 q=q->next;
222 r=r->next;
223 r->next=NULL;
224 }
225 }
226 if(q!=NULL)r->next=q;
227 if(p!=NULL)r->next=p;
228 return 0;
229 }
栈
栈是一种特殊的线性表
顺序栈
sqstack.h
1 typedef int data_t;
2
3 typedef struct{
4 data_t *data;
5 int maxlen;
6 int top;
7
8 }sqstack;
9
10 sqstack* stack_create(int len);
11 int stack_free(sqstack* S);
12 int stack_clear(sqstack* S);
13 int stack_push(sqstack*S,data_t value);
14 data_t stack_pop(sqstack*S);
15 int stack_empty(sqstack* S);
16 int stack_full(sqstack* S);
17 data_t stack_top(sqstack* S);
~
sqstack.c
1 #include<stdio.h>
2 #include<stdlib.h>
3 #include<string.h>
4 #include "sqstack.h"
5
6 sqstack* stack_create(int len){
7 sqstack* S;
8 S=(sqstack*)malloc(sizeof(sqstack));
9 if(S==NULL){
10 printf("malloc sqstack failed\n");
11 return NULL;
12 }
13
14 S->data=(data_t*)malloc(len*sizeof(data_t));
15 if(S->data==NULL){
16 printf("malloc data_t failed\n");
17 return NULL;
18 }
19
20 memset(S->data,0,len*sizeof(data_t));
21 S->maxlen=len;
22 S->top=-1;
23 return S;
24
25
26 }
27 int stack_free(sqstack* S){
28 if(S==NULL){
29 printf("S is NULL\n");
30 return -1;
31 }
32
33 if(S->data!=NULL){
34 free(S->data);
35 }
36 free(S);
37 return 0;
38 }
39 int stack_clear(sqstack* S){
40 if(S->top==-1){
41 printf("S is clear\n");
42 }
43 S->top=-1;
44 return 0;
45 }
46 int stack_push(sqstack*S,data_t value){
47 if(S==NULL){
48 printf("S is NULL\n");
49 return -1;
50 }
51 S->top++;
52 S->data[S->top]=value;
53
54 return 0;
55 }
56 data_t stack_pop(sqstack*S){
57 if(S->top==-1){
58 printf("data is NULL\n");
59 return -1;
60 }
61 return S->data[S->top--];
62 }
63 /*
64 *
65 *@ret 1-empty
66 */
67 int stack_empty(sqstack* S){
68 if(S==NULL){
69 printf("S is NULL\n");
70 return -1;
71 }
72 return (S->top==-1?1:0);
73
74 }
75 /*
76 *
77 *@ret 1-full
78 */
79 int stack_full(sqstack* S){
80 if(S==NULL){
81 printf("S is NULL\n");
82 return -1;
83 }
84
85 return (S->top==S->maxlen-1?1:0);
86 }
87 data_t stack_top(sqstack* S){
88 if(S==NULL){
89 printf("S is NULL\n");
90 return -1;
91 }
92 return S->data[S->top];
93 }
链表栈
linksatck.h
1 typedef int data_t;
2
3 typedef struct node{
4 data_t data;
5 struct node* next;
6 }stacknode,*linkstack;
7
8 linkstack stack_create();
9 int stack_push(linkstack s,data_t value);
10 data_t stack_pop(linkstack s);
11 int stack_empty(linkstack s);
12 data_t stack_top(linkstack s);
13 linkstack stack_free(linkstack s);
~
linksatc.c
1 #include<stdio.h>
2 #include<stdlib.h>
3 #include "linkstack.h"
4
5 linkstack stack_create(){
6 linkstack s;
7 s=(linkstack)malloc(sizeof(stacknode));
8 if(s==NULL){
9 printf("malloc is failed\n");
10 return NULL;
11 }
12 s->data=0;
13 s->next=NULL;
14 return s;
15 }
16 int stack_push(linkstack s,data_t value){
17 if(s==NULL){
18 printf("s is NULL\n");
19 return -1;
20 }
21 linkstack p;
22 p=(linkstack)malloc(sizeof(stacknode));
23 if(p==NULL){
24 return -1;
25 }
26 p->data=value;
27
28 p->next=s->next;
29 s->next=p;
30 return 0;
31 }
32
33 data_t stack_pop(linkstack s){
34 if(s==NULL)return -1;
35 linkstack p;
36 data_t value;
37
38 p=s->next;
39 s->next=p->next;
40 value=p->data;
41 free(p);
42 p=NULL;
43 return value;
44
45 }
46 int stack_empty(linkstack s){
47 if(s==NULL)return -1;
48 return (s->next==NULL?1:0);
49 }
50 data_t stack_top(linkstack s){
51 if(s==NULL)return -1;
52 return s->next->data;
53
54 }
55 linkstack stack_free(linkstack s){
56 if(s==NULL)return NULL;
57 linkstack p;
58
59 while(s!=NULL){
60 p=s;
61 s=s->next;
62 printf("free:%d\n",p->data);
63 free(p);
64 }
65 s=NULL;
66 return s;
67
68 }
队列
定义:只能限制在两端进行插入和删除的线性表
特点
队列是限制在两端进行插入操作和删除操作的线性表
允许进行存入操作的一端称为“队尾”
允许进行删除操作的一端称为“队头”
当线性表中没有元素时,称为“空队”
特点 :先进先出(FIFO)
队列操作示意图:
sequeue.h
1 typedef int data_t;
2
3 #define N 128
4
5 typedef struct{
6 data_t data[N];
7 int front,rear;
8
9 }sequeue;
10
11 sequeue* queue_create();
12 int enqueue(sequeue* sq,data_t value);
13 data_t dequeue(sequeue* sq);
14 int queue_empty(sequeue* sq);
15 int queue_full(sequeue* sq);
16 int queue_clear(sequeue* sq);
17 sequeue* queue_free(sequeue*sq);
~
sequeue.c
1 #include<stdio.h>
2 #include<stdlib.h>
3 #include<string.h>
4 #include "sequeue.h"
5
6
7 sequeue* queue_create(){
8 sequeue* sq;
9 sq=(sequeue*)malloc(sizeof(sequeue));
10 if(sq==NULL){
11 printf("malloc failed\n");
12 return NULL;
13 }
14 memset(sq->data,0,sizeof(sq->data));
15 sq->front=sq->rear=0;
16 return sq;
17
18 }
19 int enqueue(sequeue* sq,data_t value){
20 if(sq==NULL){
21 printf("sq is NULL\n");
22 return -1;
23 }
24
25 if(((sq->rear+1)%N)==sq->front){
26 printf("sq is full\n");
27 return -1;
28 }
29 sq->data[sq->rear]=value;
30 sq->rear=(sq->rear+1)%N;
31 return 0;
32 }
33 data_t dequeue(sequeue* sq){
34
35 if(sq==NULL){
36 printf("sq is NULL\n");
37 return -1;
38 }
39 data_t ret;
40 ret=sq->data[sq->front];
41 sq->front=(sq->front+1)%N;
42 return ret;
43
44 }
45 int queue_empty(sequeue* sq){
46
47 if(sq==NULL){
48 printf("sq is NULL\n");
49 return -1;
50 }
51 return (sq->front==sq->rear?1:0);
52
53 }
54 int queue_full(sequeue* sq){
55
56 if(sq==NULL){
57 printf("sq is NULL\n");
58 return -1;
59 }
60 return (((sq->rear+1)%N)==sq->front?1:0);
61
62 }
63 int queue_clear(sequeue* sq){
64 if(sq==NULL){
65 printf("sq is NULL\n");
66 return -1;
67 }
68 sq->rear=sq->front=0;
69 return 1;
70
71 }
72 sequeue* queue_free(sequeue*sq){
73
74 if(sq==NULL){
75 printf("sq is NULL\n");
76 return NULL;
77 }
78
79 free(sq);
80 sq=NULL;
81 return NULL;
82
83 }
链式队列
linkqueue.h
2
3 typedef struct node{
4 data_t data;
5 struct node* next;
6
7 }listnode,*linklist;
8
9 typedef struct {
10 linklist front,rear;
11 }linkqueue;
12
13 linkqueue* queue_create();
14 int enqueue(linkqueue* lq,data_t value);
15 data_t dequeue(linkqueue* lq);
16 int queue_empty(linkqueue* lq);
17 int queue_clear(linkqueue* lq);
18 linkqueue* queue_free(linkqueue* lq);
linkqueue.c
1 #include<stdio.h>
2 #include<stdlib.h>
3 #include"linkqueue.h"
4
5
6 linkqueue* queue_create(){
7 linkqueue* lq;
8 if((lq=(linkqueue*)malloc(sizeof(linkqueue)))==NULL){
9 printf("malloc lq failed\n");
10 return NULL;
11 }
12 lq->front=lq->rear=(linklist)malloc(sizeof(listnode));
13 if(lq->front==NULL){
14 printf("malloc linknode failed\n");
15 return NULL;
16 }
17 lq->front->data=0;
18 lq->front->next=NULL;
19 return lq;
20
21 }
22 int enqueue(linkqueue* lq,data_t value){
23 if(lq==NULL){
24 printf("lq is NULL\n");
25 return -1;
26 }
27 linklist p;
28 if((p=(linklist)malloc(sizeof(listnode)))==NULL){
29 printf("malloc listnode failed\n");
30 return -1;
31 }
32 p->data=value;
33 p->next=NULL;
34
35 lq->rear->next=p;
36 lq->rear=p;
37 return 0;
38
39 }
40 data_t dequeue(linkqueue* lq){
41 if(lq==NULL){
42 printf("lq is NULL\n");
43 return -1;
44 }
45
46 linklist p;
47 p=lq->front;
48 lq->front=p->next;
49 free(p);
50 p=NULL;
51 return lq->front->data;
52
53 }
54 int queue_empty(linkqueue* lq){
55 if(lq==NULL){
56 printf("lq is NULL\n");
57 return -1;
58 }
59
60 return (lq->front==lq->rear?1:0);
61
62 }
63 int queue_clear(linkqueue* lq){
64 if(lq==NULL){
65 printf("lq is NULL\n");
66 return -1;
67
68 }
69 linklist p;
70 while(lq->front->next!=NULL){
71 p=lq->front;
72 lq->front=p->next;
73 printf("clear:%d\n",p->data);
74 free(p);
75 }
76 return 0;
77
78 }
79 linkqueue* queue_free(linkqueue* lq){
80 if(lq==NULL){
81 printf("la is null\n");
82 }
83 linklist p;
84 while(lq->front!=NULL){
85 p=lq->front;
86 lq->front=p->next;
87 printf("free:%d\n",p->data);
88 free(p);
89 }
90 free(lq);
91 lq=NULL;
92 return NULL;
93
94
95 }
球钟问题
test.c
1 #include<stdio.h>
2 #include "sqstack.h"
3 #include "linkqueue.h"
4 int check_queue(linkqueue* lq);
5 int main(){
6 linkqueue *lq;
7 if((lq=queue_create())==NULL){
8 printf("lq create failed\n");
9 return -1;
10 }
11 for(int i=0;i<27;i++){
12 enqueue(lq,i+1);
13 }
14 //create three stack
15 sqstack *s_hour,*s_five,*s_min;
16 if((s_hour=stack_create(11))==NULL){
17 printf("s_hour satck create failed\n");
18 return -1;
19 }
20
21 if((s_five=stack_create(11))==NULL){
22 printf("s_five satck create failed\n");
23 return -1;
24 }
25
26 if((s_min=stack_create(4))==NULL){
27 printf("s_min satck create failed\n");
28 return -1;
29 }
30 int min=0;
31 while(1){
32 min++;
33 if(!queue_empty(lq)){
34
35 if(!stack_full(s_min)){
36 stack_push(s_min,dequeue(lq));
37 }else{
38 while(!stack_empty(s_min))
39 enqueue(lq,stack_pop(s_min));
40 if(!stack_full(s_five))
41 stack_push(s_five,dequeue(lq));
42 else{
43 while(!stack_empty(s_five))
44 enqueue(lq,stack_pop(s_five));
45 if(!stack_full(s_hour))
46 stack_push(s_hour,dequeue(lq));
47 else{
48 while(!stack_empty(s_hour))
49 enqueue(lq,stack_pop(s_hour));
50 //0:0
51 enqueue(lq,dequeue(lq));
52 if(check_queue(lq)){
53 printf("min=%d\n",min);
54 break;
55 }
56 }
57
58 }
59
60 }
61 }
62 }
63
64 printf("free:");
65 while(!queue_empty(lq)){
66 printf("%d ",dequeue(lq));
67
68 }
69 puts("");
70 return 0;
71
72 }
73 int check_queue(linkqueue* lq){
74 if(lq==NULL){
75 printf("lq is NULL\n");
76 return -1;
77 }
78
79 linklist p;
80 p=lq->front->next;
81 while(p && p->next){
82 if(p->next->data<p->data)return 0;
83 p=p->next;
84 }
85 return 1;
86
87 }
树
主要掌握程序递归思想:
递归:自己调用自己
递归算法要素:
1.算法规律
2.终止条件
树相关概念
**树的逻辑结构 **:树中任何节点都可以有零个或多个直接后继节点(子节点),但至多只有一个直接前趋节点(父节点),根节点没有前趋节点,叶节点没有后继节点。
二叉树
tree.h
数据结构:
根节点,左子树和右子树,一切操作主要是围绕根节点开始(类似于单链表的头结点)
1 #ifndef _TREE_H_
2 #define _TREE_H_
3 typedef char data_t;
4
5 typedef struct node_t{
6 data_t data;
7 struct node_t* left;
8 struct node_t* right;
9 }bitree;
10
11 bitree* tree_create();
12 void preorder(bitree* r);
13 void inorder(bitree* r);
14 void postorder(bitree* r);
15 void layerorder(bitree* r);
16
17 #endif
先序、中序、后序遍历
先访问树根,再访问左子树,最后访问右子树;(先序)
先访问左子树,再访问树根,最后访问右子树;(中序)
先访问左子树,再访问右子树,最后访问树根;(后序)
层序遍历:一层一层访问节点数据
先序算法设计思想:
终止条件:节点为NULL
算法规律:
1.根节点开始,先访问根节点;printf(“%c”,r->data);
2.访问左子树
3.访问右子树
1 #include<stdio.h>
2 #include<stdlib.h>
3 #include"tree.h"
4 #include "linkqueue.h"
5 bitree* tree_create(){
6 bitree* r;
7 data_t value;
8 scanf("%c",&value);
9 if(value=='#'){
10 return NULL;
11 }
12
13 if((r=(bitree*)malloc(sizeof(bitree)))==NULL){
14 printf("malloc bitree failend\n");
15 return NULL;
16 }
17 r->data=value;
18 r->left=tree_create();
19 r->right=tree_create();
20 return r;
21
22
23 }
24 void preorder(bitree* r){
25 if(r==NULL){
26 return;
27 }
28 printf("%c",r->data);
29 preorder(r->left);
30 preorder(r->right);
31
32 }
33 void inorder(bitree* r){
34 if(r==NULL){
35 return;
36 }
37 inorder(r->left);
38 printf("%c",r->data);
39 inorder(r->right);
40
41 }
42 void postorder(bitree* r){
43 if(r==NULL){
44 return;
45 }
46 postorder(r->left);
47 postorder(r->right);
48 printf("%c",r->data);
49
50 }
51 void layerorder(bitree* r){
52 linkqueue *lq;
53 if((lq=queue_create())==NULL){
54 return;
55 }
56 if(r==NULL){
57 return;
58 }
59 printf("%c",r->data);
60 enqueue(lq,r);
61 while(!queue_empty(lq)){
62 r=dequeue(lq);
63 if(r->left){
64 printf("%c",r->left->data);
65 enqueue(lq,r->left);
66 }
67 if(r->right){
68 printf("%c",r->right->data);
69 enqueue(lq,r->right);
70 }
71
72 }
73
74
75 }
层序遍历算法思想:
一层一层遍历循环
之前先序遍历是节点到哪就把哪打印出来,所以不需要存储上一个节点,而层序遍历是一层一层遍历,所以需要知道上一个节点的数据,才能找到他的左子树和右子树。因此,这里需要引入队列数据结构,将访问完的节点存储在队列中,然后出队列找其左子树和右子树,开始新一轮遍历节点。
查找
hash表
hash表的查找:又称质数除余法,设Hash表空间长度为m,选取一个不大于m的最大质数p,令:H(key)=key%p
处理冲突的方法:链地址法
hash.h
1 #ifndef _HASH_H_
2 #define _HASH_H_
3
4 typedef int datatype;
5
6 typedef struct node_t{
7 datatype key;
8 datatype data;
9 struct node_t* next;
10 }listnode,*linklist;
11
12 #define N 15
13 typedef struct{
14 listnode data[N];
15 }hashlist;
16
17 hashlist* hash_create();
18 int hash_insert(hashlist* hl,datatype key);
19 linklist hash_search(hashlist* hl,datatype key);
20
21
22 #endif
hash.c
1 #include<stdio.h>
2 #include<stdlib.h>
3 #include<string.h>
4 #include"hash.h"
5
6
7 hashlist* hash_create(){
8 hashlist* hl;
9 if((hl=(hashlist*)malloc(sizeof(hashlist)))==NULL){
10 printf("hashlist mallocfailed\n");
11 return NULL;
12 }
13
14 memset(hl,0,sizeof(hashlist));
15 return hl;
16 }
17 int hash_insert(hashlist* hl,datatype key){
18 if(hl==NULL){
19 printf("hl is NULL\n");
20 return -1;
21 }
22 linklist p;
23 if((p=(linklist)malloc(sizeof(listnode)))==NULL){
24
25 printf("malloc listnode failed\n");
26 return -1;
27 }
28 p->key=key;
29 p->data=key%N;
30 p->next=NULL;
31
32 linklist q;
33 q=&hl->data[key%N];
34
35 while(q->next && q->next->key<p->key){
36 q=q->next;
37 }
38 p->next=q->next;
39 q->next=p;
40 return 0;
41
42
43 }
44 linklist hash_search(hashlist* hl,datatype key){
45 if(hl==NULL){
46 printf("hl is NULL\n");
47 return NULL;
48 }
49 datatype x=key%N;
50 linklist p=&hl->data[x];
51 while(p->next && p->key!=key){
52 p=p->next;
53 }
54 if(p->next==NULL){
55 // printf("not found");
56 return NULL;
57 }else {
58 // printf("found:%d %d",key,p->key);
59 return p;
60
61 }
62
63
64 }
排序
quick_sort.c
1 #include<stdio.h>
2 #include<stdlib.h>
3
4
5 #define N 15
6 int quick_sort(int* data,int low,int high);
7 int partion(int* data,int low,int high);
8 int compare(const void*p1,const void*p2);
9 int main(){
10 int data[N]={0};
11 srandom(10);
12 for(int i=0;i<N;i++){
13 data[i]=random()%100;
14 }
15
16 for(int i=0;i<N;i++){
17 printf("%d ", data[i]);
18 }
19 puts("");
20
21 // quick_sort(data,0,N-1);
22 qsort(data,N,sizeof(int),compare);
23
24 for(int i=0;i<N;i++){
25 printf("%d ", data[i]);
26 }
27 puts("");
28
29 return 0;
30
31 }
32 int quick_sort(int* data,int low,int high){
33 if(data==NULL){
34 return -1;
35 }
36 if(low>=high){
37 return 0;
38 }
39 int t;
40 t=partion(data,low,high);
41 quick_sort(data,low,t-1);
42 quick_sort(data,t+1,high);
43 return 0;
44
45
46 }
47
48 int partion(int* data,int low,int high){
49 if(data==NULL){
50 return -1;
51 }
52 int temp=data[low];
53
54 while(low<high){
55 while(low<high && temp<=data[high]){
56 high--;
57 }
58 data[low]=data[high];
59 while(low<high && temp>=data[low]){
60 low++;
61 }
62 data[high]=data[low];
63
64 }
65 data[low]=temp;
66 return low;
67
68 }
69 int compare(const void*p1,const void*p2){
70 return(*(const int*)p1-*(const int*)p2);
71
72 }