您的位置:首页 > 理论基础 > 数据结构算法

数据结构学习笔记 --- 线性表 (一些常见的关于链表的算法和面试题)

2012-02-07 22:04 1011 查看
1. 引言

本文主要讲解一些常见的关于链表的算法和面试题。

2. 单链表的反序(不带头结点)

/* 不带头结点的单链表逆转 */

#include "ds.h"
using namespace std;

typedef 	int		ElemType;

typedef struct LNode{
ElemType 		data;
struct LNode	*next;
}LNode, *LinkList;

void InitList(LinkList &L);
void TailCreList(LinkList &L, int n);
void ReverseList(LinkList &L);
void TraverseList(LinkList L);

void InitList(LinkList &L)
{
L = NULL;
}

void TailCreList(LinkList &L, int n)
{
LinkList 	p, tail, s;
int 		i;

if (0 > n)
return;

tail = L;

printf("please input %d number:", n);

for (i = 1; i <= n; i++)
{
s = (LinkList)malloc(sizeof(LNode));
scanf("%d", &(s->data));
if (1 == i)
{
s->next = tail;
L = tail = s;
}
else
{
tail->next = s;
tail = tail->next;
}
}
tail->next = NULL;
}

void ReverseList(LinkList &L)
{
LinkList 	pre_pre, pre, cur;

// 链表为空和只有一个元素时不用逆转
if (NULL == L || NULL == L->next)
return;

cur = L;
pre = NULL;

// 从第二个元素开始逆转,
while (cur->next)
{
// pre_pre, pre, cur 向前移动
pre_pre = pre;
pre = cur;
cur = cur->next;

// 开始逆转
pre->next = pre_pre;
}

// 将最后一个结点指向其前驱
cur->next = pre;
// 头指针指向最后一个结点L
L = cur;
}

void TraverseList(LinkList L)
{
LinkList 	p = L;
while (p)
{
printf("%d ", p->data);
p = p->next;
}
printf("\n");
}

int main()
{
LinkList 	L;

InitList(L);
TailCreList(L, 5);
TraverseList(L);

ReverseList(L);
TraverseList(L);
}


3. 输入一个单向链表,输出该链表中倒数第 k 个结点。

// 输入一个单向链表,输出该链表中倒数第 k 个结点。

#include "ds.h"
using namespace std;

typedef 	int		ElemType;

typedef struct LNode{
ElemType 		data;
struct LNode	*next;
}LNode, *LinkList;

void InitList(LinkList &L);
void TailCreList(LinkList &L, int n);
int OutputLast_K(LinkList L, int k);
void TraverseList(LinkList L);

void InitList(LinkList &L)
{
L = NULL;
}

void TailCreList(LinkList &L, int n)
{
LinkList 	p, tail, s;
int 		i;

if (0 > n)
return;

tail = L;

printf("please input %d number:", n);

for (i = 1; i <= n; i++)
{
s = (LinkList)malloc(sizeof(LNode));
scanf("%d", &(s->data));
if (1 == i)
{
s->next = tail;
L = tail = s;
}
else
{
tail->next = s;
tail = tail->next;
}
}
tail->next = NULL;
}

/*
返回值说明:
0 	-> 输出成功
-1 	-> 链表为空或k<1
-2  -> 链表长度小于k
*/

int OutputLast_K(LinkList L, int k)
{
LinkList 	p_k = L, p_add_k = L;
int 		i = 0;

// 链表为空和k<1
if (NULL == L || k < 1)
{
if (k < 1)
printf("k < 1 \n");
return -1;
}

// 当p_add_k到链表尾部时,p_k到倒数第k个结点处
while (p_add_k)
{
if (i < k)
{
i++;
}
else
{
p_k = p_k->next;
}
p_add_k = p_add_k->next;
}

// 链表长度大于等于K
if (i == k)
{
while (p_k)
{
printf("%d ", p_k->data);
p_k = p_k->next;
}
printf("\n");
}
// 链表长度小于K
else
{
printf("List L less %d element.\n", k);
return -2;
}

return 0;
}

void TraverseList(LinkList L)
{
LinkList 	p = L;
while (p)
{
printf("%d ", p->data);
p = p->next;
}
printf("\n");
}

int main()
{
LinkList 	L;

InitList(L);
TailCreList(L, 5);
TraverseList(L);

for (int i = 0; i < 8; i++ )
OutputLast_K(L, i);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐