注:看面试题时,主要应该以学习为主,面试题有些基本上是我们编程时会遇上的问题,通过学习面试题会提升我们的编程意识和解决一些日常我们编程所遇到的问题,看完这篇面试题后,希望能对你有所帮助,另外题中有问题的地方可以在评论区指出,在这里谢谢您的观看。
非连续、非顺序 的 存储结构数据域和指针域思路:使用快慢指针,快的指针一次移动两个节点,慢的指针一次移动一个结点,两个指针都从起始位置出发,当慢指针与快指针相遇时,则说明有环,如下图所示。

代码编写:
list_ring.h:
#ifndef LIST_RING_H_
#define LIST_RING_H_
#include
#include
#include
typedef int data_t; //储存的数据类型
typedef struct LinkList //链表结构体
{
data_t data;
struct LinkList *next;
}linknode, *linklist;
linklist link_list_init(void); //链表初始化
void link_list_destroy(linklist H); //链表销毁
int link_ring_create(linklist H); //链表环创建
linknode *check_list_ring(linklist H); //检查链表是否存在环
#endif
list_ring.c:
#include "list_ring.h"
linklist link_list_init()
{
linklist H = (linklist)malloc(sizeof(linknode));
if(H == NULL)
return NULL;
H->data = 0;
H->next = NULL;
return H;
}
void link_list_destroy(linklist H)
{
assert(H);
linknode *p = H;
while(p)
{
H = H->next;
free(p);
p->next = NULL;
p = H;
}
p = NULL;
}
int link_ring_create(linklist H)
{
assert(H);
int i;
linklist q = H;
linknode *p = NULL;
for(i = 0; i < 10; i++)
{
p = (linklist)malloc(sizeof(linknode));
if(p == NULL)
{
printf("linknode create error!\r\n");
return -1;
}
p->data = i;
p->next = NULL;
q->next = p;
q = q->next;
}
p->next = H->next->next->next;
return 0;
}
linknode *check_list_ring(linklist H)
{
assert(H);
linknode *fast, *slow; //快慢指针
fast = H;
slow = H;
if(fast->next != NULL)
{
while(fast->next)
{
fast = fast->next->next;
slow = slow->next;
if(fast == slow)
{
return fast; //有环
}
}
return NULL; //没有环
}
else
{
return NULL;
}
}
test.c:
#include "list_ring.h"
int main(int argc, const char *argv[])
{
int ret = 0;
linknode *p = NULL;
linklist H = link_list_init();
if(H == NULL)
{
printf("linklist init error!\r\n");
return -1;
}
ret = link_ring_create(H);
if(ret != 0)
{
link_list_destroy(H);
H = NULL;
printf("link ring create error!\r\n");
return -1;
}
p = check_list_ring(H);
if(p != NULL)
{
printf("list has a ring!\r\n");
printf("The value of the encounter node is %d\r\n", p->data);
free(p);
}
else
{
printf("list has no ring!\r\n");
}
link_list_destroy(H);
return 0;
}
运行结果:


思路:根据这张图,在相遇点时,快指针走过的结点为n+2*x+y, 慢指针走过的结点是x+n,快指针是慢指针的2倍,所以有 n+2*x+y = 2*(x+y);得 n = y; 因此得到环的起始点的地址 一个相遇点指针与 一个头结点指针两者同时移动,当两者相等时,指针指向的就是起始点的地址。
代码:
linknode *initial_ring_node_get(linklist H, linknode *p)
{
assert(H);
assert(p);
while(p->next != NULL || H->next != NULL)
{
p = p->next;
H = H->next;
if(p == H)
return H;
}
return NULL;
}

思路:保存相遇点,让指针从相遇点走一圈计算结点数
代码:
int node_number_get(linknode *p)
{
assert(p);
int i = 1;
linknode *q = p->next;
while(q != p)
{
if(q->next == NULL)
{
return -1;
}
q = q->next;
i++;
}
return i;
}
栈(stack)是仅限在表尾进行插入和删除的线性表。对于栈来说:
先进先出 的线性表(FIFO)题目:给定一个字符串,由一下字符组成,‘(’、‘[’、‘{’、‘)’、‘]’、‘}’,以‘()’、‘[]’、‘{}’,这样的组合为括号配对成功,示例如下:
s = '()[]{}' 输出为ture
s = '[{}()]' 输出为ture
s = ‘[{([])}]’ 输出为ture
s = ''[{]}
代码:
stack_symbol.h:
#ifndef STACK_SYMBOL_H_
#define STACK_SYMBOL_H_
#include
#include
#include
typedef char data_t;
typedef struct Stack_Symbol
{
data_t *data_space; //数据空间指针
int top; //数据栈顶指针
int maxlen; //数据最大储存空间
}StackSymbol;
StackSymbol *stack_symbol_create(int len);
void stack_symbol_enter(StackSymbol *st, data_t data);
data_t stack_symbol_out(StackSymbol *st);
int symbol_judge(StackSymbol *st, const char *str);
#endif
stack_symbol.c:
#include "stack_symbol.h"
StackSymbol *stack_symbol_create(int len)
{
StackSymbol *p = (StackSymbol *)malloc(sizeof(StackSymbol));
if(p == NULL)
{
printf("symbol stack create error!\r\n");
return NULL;
}
p->data_space = (data_t *)malloc(len*sizeof(data_t));
if(p->data_space == NULL)
{
printf("data space create error!\r\n");
return NULL;
}
p->top = 0;
p->maxlen = len;
return p;
}
void stack_symbol_enter(StackSymbol *st, data_t data)
{
assert(st);
int newlen = 0;
if(st->top == st->maxlen) //栈满了
{
newlen = st->maxlen == 0? 4 : 2*st->maxlen;
st->data_space = (data_t *)realloc(st, st->maxlen*sizeof(data_t));
if(st->data_space == NULL)
{
printf("data space assignment failure!\r\n");
exit(-1);
}
st->maxlen = newlen;
}
st->data_space[st->top] = data;
st->top++;
}
data_t stack_symbol_out(StackSymbol *st)
{
int OutData = 0;
assert(st);
if(st->top == 0)
{
printf("stack is empty!\r\n");
return 0;
}
OutData = st->data_space[st->top-1];
st->data_space[st->top-1] = 0;
st->top--;
return OutData;
}
int symbol_judge(StackSymbol *st, const char *str)
{
assert(st);
assert(str);
data_t c = 0;
while(*str != '\0')
{
if(*str == '(' || \
*str == '[' || \
*str == '{')
{
stack_symbol_enter(st, *str);
str++;
}
else
{
c = stack_symbol_out(st);
if(c == 0)
return 0;
if((c == '(' && *str != ')') || \
(c == '[' && *str != ']') || \
(c == '{' && *str != '}'))
{
return 0;
}
else
str++;
}
}
return 1;
}
test.c:
#include "stack_symbol.h"
int main(int argc, const char *argv[])
{
int ret = 0;
const char *str1 = "()[]{}";
const char *str2 = "[{}()]";
const char *str3 = "[{([])}]";
const char *str4 = "[{]}";
StackSymbol *st = stack_symbol_create(10);
if(st == NULL)
return -1;
ret = symbol_judge(st, str1);
if(ret == 1)
printf("str1 is true\r\n");
else
printf("str1 is false\r\n");
ret = symbol_judge(st, str2);
if(ret == 1)
printf("str2 is true\r\n");
else
printf("str2 is false\r\n");
ret = symbol_judge(st, str3);
if(ret == 1)
printf("str3 is true\r\n");
else
printf("str3 is false\r\n");
ret = symbol_judge(st, str4);
if(ret == 1)
printf("str4 is true\r\n");
else
printf("str4 is false\r\n");
return 0;
}
运行现象:

