您的位置:首页 > 其它

单链表操作-待增加

2015-09-01 10:53 295 查看
单链表:

typedef struct node{

int data;

struct node* next;

}LNode;

关于但链表的操作很多(增删改查,逆序,子交并补等,以及一些经典的变式),考研题目中,有很多好的算法值得学习。

下面是C语言实现的, 采用一个method,一个test_method,方便逐个学习,这个需要不断的积累,最好用敲几遍,再在纸上多写写,只有能自己完全的写出来,才是完全的掌握。

#include <stdio.h>
#include <stdlib.h>

typedef struct node{
int data;
struct node* next;
}LNode;

LNode* newNode(int data)
{
LNode* tmp = (LNode*)malloc(sizeof(LNode));
if(tmp!= NULL)
{
tmp->data = data;
tmp->next = NULL;
}
return tmp ;
}

// 头插法
LNode* insert1(int a[],int len)
{
LNode* head = newNode(0);
int i;
for(i = 0 ; i < len ; i ++)
{
int data = a[i];
LNode *tmp = newNode(data);
tmp->next = head->next;
head->next = tmp;
}
return head;
}

// 尾插法
LNode* insert2(int a[],int len)
{
LNode* head = newNode(0);
LNode* rear = head;
int i;
for(i = 0 ; i < len ; i ++)
{
int data = a[i];
LNode *tmp = newNode(data);
rear->next = tmp ;
rear = tmp ;
}
return head;
}

void printLink(LNode* head)
{
if(head == NULL || head->next == NULL)
{
printf("Empty\n");
return ;
}
LNode* t = head->next;
while(t != NULL)
{
printf("%d ",t->data);
t = t->next;
}
printf("\n");
}

void test_insert1()
{
int a[10] = {1,3,2,7,5,4,9,2,0};
int len = 5;
LNode* head = insert1(a,len);
printLink(head);
}

void test_insert2()
{
int a[10] = {1,3,2,7,5,4,9,2,0};
int len = 5;
LNode* head = insert2(a,len);
printLink(head);
}

// 直接插入排序
void sortLink(LNode* head)
{
if(head == NULL || head->next == NULL)
return ;
LNode* r = head->next->next;//第二个元素 开始
head->next->next = NULL;
while(r != NULL)
{
int nowdata = r->data ;
LNode* pre;
LNode* scan;
for(pre = head,scan = head->next;scan != NULL;pre=pre->next,scan = scan->next)
{
if(scan->data > nowdata)
{
break;
}
}
LNode* tmp = r ;// pre 和 scan 之间插入 tmp 这个节点
r = r->next; // r 取下一个
tmp->next = scan;
pre->next = tmp ;
}
}

void test_sortLink()
{
int a[10] = {1,3,2,7,5,4,9,2,0};
int len = 5;
LNode* head = insert2(a,len);
printLink(head);
sortLink(head);
printLink(head);
}

// 反转链表,也就是采用头插法
void reverseLink(LNode* head)
{
if(head == NULL || head->next == NULL)
return ;
LNode* r = head->next->next;//第二个元素 开始
head->next->next = NULL;

while(r != NULL)
{
LNode* tmp = r; // tmp是当前要插入的
r = r->next; //  r 取下一个
tmp->next = head->next;
head->next = tmp ;
}
}

void test_reverseLink()
{
int a[10] = {1,3,2,7,5,4,9,2,0};
int len = 5;
LNode* head = insert2(a,len);
printLink(head);
reverseLink(head);
printLink(head);
}

// 删除指定元素 利用pre  p  找到一个删除一个 , 查找 插入等都差不多做法
void delLink(LNode* head,int deldata)
{
if(head == NULL || head->next == NULL)
return ;
LNode* pre = head;
LNode* scan = head->next;
while(scan!= NULL)
{
if(scan->data == deldata)
{
LNode* tmp = scan;
scan = scan->next ;
pre->next = scan;
free(tmp);
}else{
pre = scan;
scan = scan->next;
}
}
}

void test_delLink()
{
int a[10] = {2,3,2,7,5,4,9,2,0};
int len = 5;
LNode* head = insert2(a,len);
printf("原始序列:");
printLink(head);
delLink(head,2);
printf("删除 data = 2的节点后:");
printLink(head);
}

/*
找到倒数第k个元素(k取1到Len(len为Link长度)) 如果可以 实现需要判断下 取模等操作处理(重要)
比如 1 3 2 7 5 倒数第2个为7 倒数第4个为3
*/
LNode* searchLastK(LNode* head , int k)
{
if(head == NULL || head->next == NULL)
return NULL;
LNode* p = head->next;
LNode* q = head->next;
int i;
for(i = 0 ; i < k ; i ++) // q移动到第k个位置 这样 p q 相距为 k
{
q = q->next;
}
// p q 一起移动, q移动到链表尾部 , 则 p 就是倒数第k个节点
while(q != NULL)
{
q = q->next;
p = p->next;
}
return p;
}

void test_searchLastK()
{
int a[10] = {2,3,2,7,5,4,9,2,0};
int len = 5;
LNode* head = insert2(a,len);
printf("原始序列:");
printLink(head);
int k = 2 ;
LNode* ln = searchLastK(head , k);
printf("倒数第%d个:%d\n",k,ln->data);
}

int main()
{
//freopen("in.txt","r",stdin);
//test_insert1();
//test_insert2();
//test_sortLink();
//test_reverseLink();
//test_delLink();
test_searchLastK();
return 0 ;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: