<pre name="code" class="cpp">
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct Node
{
int data;
struct Node *next;
} Node, *LinkedList;
//头插入法
LinkedList createH(int arr[])
{
//int arr[5] = {2, 4, 6, 1, 3};
LinkedList L;
L = (LinkedList) malloc(sizeof(Node));
L->next = NULL;
int i = 0;
while (i < 5)
{
LinkedList p;
p = (LinkedList) malloc(sizeof(Node));
p->data = arr[i];
p->next = L->next;
L->next = p;
i++;
}
return L;
}
//尾插入法
LinkedList createT(int arr[])
{
LinkedList L;
L = (LinkedList) malloc(sizeof(Node));
L->next = NULL;
Node *t;
t = L;
int i = 0;
while (i < 5)
{
LinkedList p;
p = (LinkedList) malloc(sizeof(Node));
p->data = arr[i];
t->next = p;
t = p;
i++;
}
t->next = NULL;
return L;
}
//打印循环链表
LinkedList createCircle(int arr[])
{
LinkedList L;
L = (LinkedList) malloc(sizeof(Node));
L->next = NULL;
Node *t;
t = L;
int i = 0;
while (i < 5)
{
LinkedList p;
p = (LinkedList) malloc(sizeof(Node));
p->data = arr[i];
t->next = p;
t = p;
i++;
}
t->next = L->next;
return L;
}
LinkedList insert(LinkedList L, int point, int x)
{
Node *p = L;
int i;
for (i = 1; i < point; i++)
{
p = p->next;
}
Node *tmp = (LinkedList) malloc(sizeof(Node));
tmp->data = x;
tmp->next = p->next;
p->next = tmp;
return L;
}
LinkedList deldata(LinkedList L, int x)
{
Node *p = L;
Node *pre = L;
while (p->next)
{
if (p->data == x)
{
pre->next = p->next;
free(p);
break;
}
pre = p;
p = p->next;
}
return L;
}
void print(LinkedList L)
{
LinkedList p = L->next;
while (p)
{
printf("%d ", p->data);
p = p->next;
}
printf("\n");
}
//测试循环链表
void printClircleTest(LinkedList L)
{
LinkedList p = L->next;
int i = 0;
while (p && i < 8)
{
printf("%d ", p->data);
p = p->next;
i++;
}
printf("\n");
}
//约瑟夫问题:m个人围城一圈,每间隔n则退出
void joseph(LinkedList L,int m, int n)
{
int i = 0;
int count = 0;
Node *p = L->next;
Node *pre = L->next;
while (p && count < m)
{
if (i == n)
{
printf("%d ", p->data);
pre->next = p->next;
free(p);
i = 0;
count++;
p = pre->next;
continue;
}
pre = p;
p = p->next;
i++;
}
printf("\n");
}
//链表反转
LinkedList reverse(LinkedList list)
{
Node *tmp = NULL;
Node *p = NULL;
if (list == NULL)
{
return NULL;
}
tmp = list->next;
while (tmp->next != NULL)
{
p = tmp->next;
tmp->next = p->next;
p->next = list->next;
list->next = p;
}
return list;
}
//2个有序单链表合并,有问题
LinkedList mergeTwoSortList(LinkedList L1, LinkedList L2)
{
LinkedList p1 = L1->next;
LinkedList p2 = L2->next;
LinkedList tmp2 = L2->next;
while (p1->next && p2->next)
{
if (p2->data > p1->data && p2->data <= p1->next->data)
{
tmp2 = p2->next;
p2->next = p1->next;
p1->next = p2;
p2 = tmp2;
}
else
{
p2->next = p1;
L1 = p2;
}
if (!p1 && p2) //链表1遍历完,直接在尾巴接上链表2
{
p1->next = p2;
break;
}
if (p1 && !p2) //链表2遍历完,直接结束
{
break;
}
p1 = p1->next;
}
return L1;
}
//合并两个有序链表
Node *Merge(Node *head1,Node *head2)
{
Node *p1 = NULL;
Node *p2 = NULL;
Node *head = NULL;
//找出两个链表中第一个结点较小的结点,head记录较小结点的头结点
if(head1->next->data < head2->next->data)
{
head = head1;
p1 = head1->next;
p2 = head2->next;
}
else
{
head = head2;
p2 = head2->next;
p1 = head1->next;
}
Node *pcur = head;
//在两个链表中遍历比较,将值较小的结点链接到pcur结点后
while(p1 != NULL && p2 != NULL)
{
if(p1->data <= p2->data)
{
pcur->next = p1;
pcur = p1;
p1 = p1->next;
}
else
{
pcur->next = p2;
pcur = p2;
p2 = p2->next;
}
}
//将p1或p2剩余的结点链到pcur之后,完成整个合并的过程
if(p1 != NULL)
pcur->next = p1;
if(p2 != NULL)
pcur->next = p2;
return head;
}
//插入排序
void InsertionSort(LinkedList L)
{
LinkedList p, point, pre; /*point用来指向需要插入的结点,pre用来指向point的前一个结点*/
for(pre = L, point = L->next; point != NULL;)
{
p = L; /*p用来遍历寻找合适的插入位置*/
for(;p != point; p = p->next)
{
if(p->next->data > point->data)/*如果找到,即把point所指向的结点插到p后面,然后跳出循环*/
{
pre->next = point->next;
point->next = p->next;
p->next = point;
point = pre->next;
break; /*别忘了此处的break*/
}
}
if(p == point)/*此处需要注意,只在point所指结点不需要前插时,移动point和pre*/
{
point = point->next;
pre = pre->next;
}
}
}
/*
判断两个链表是否相交:思路:如果两个链表相交了,那么交点肯定在最后一个结点,因此问题转化为求链表最后一个结点。
各自求显得麻烦,可以先判断链表的长度,len1 和 len2,长的链表先走 | len1 - len2 |步,然后开始同时走。
*/
int length_list(Node* head)
{
int count=0;
Node* current_node = head;
if(current_node==NULL)
return 0;
else if(current_node->next==NULL)
return 1;
else{
while(current_node->next!=NULL){
count++;
current_node = current_node->next;
}
}
return count;
}
void intersection_twoLists(Node* head1,Node* head2)
{
if(head1==NULL || head2==NULL)
return;
else{
int length1 = length_list(head1);
int length2 = length_list(head2);
int step;
if(length1 >= length2){
step = length1 - length2;
for(int i=1;i<=step;i++){
head1 = head1->next;
}
}else{
step = length2 - length1;
for(int i=1;i<=step;i++){
head2 = head2->next;
}
}
while(head1->next!=NULL && head2->next!=NULL){
head1 = head1->next;
head2 = head2->next;
}
if(head1 == head2){
printf("yes");
}else{
printf("no");
}
}
}
/*1.判断链表是否有环。如果没有,快走的链表则先遍历完。如果有,一个走1步,一个走2步,最终会相遇。
2.环的长度:从碰撞点开始,再次碰撞则走过的路程就是环的长度。
3.连接点位置:分别从碰撞点、头指针开始走,相遇的那个点就是连接点。
4.链表长度:链表头到连接点+环的长度。
*/
bool hasLoop_list(Node* head)
{
bool loop = false;
Node* p1 = head;
Node* p2 = head;
if(p1==NULL || p1->next==NULL || p1->next->next==NULL)
return false;
else{
while(p2->next != NULL){
p1 = p1->next;
p2 = p2->next->next;
if(p1 == p2)
{
loop = true;
break;
}
}
}
return loop;
}
int main(void)
{
printf("start...\n");
int arr[5] = {1, 3, 6, 9, 20};
int arr2[5] = {4, 8, 10, 12, 30};
LinkedList L;
#if 0
L = createCircle(arr);
joseph(L, 5, 2);
//printClircleTest(L);
#endif
//L = createH(arr);
L = createT(arr);
print(L);
LinkedList L2;
L2 = createT(arr2);
print(L2);
L = Merge(L, L2);
print(L);
#if 0
InsertionSort(L);
print(L);
L = reverse(L);
print(L);
L = insert(L, 3, 100);
print(L);
L = deldata(L, 1);
print(L);
#endif
return 0;
}
单链表经典实现
于 2014-10-14 22:15:25 首次发布