单链表的创建与元素的增减等操作
/**
* Single Way List
* print all list after do a operator.
* task1:
* create: create a List which data is: 1, 4, 6, 2, 10, 11, 2
* add: add 3, 4, 1 to head of list (-> 3, 4, 1, 1, 4, 6, 2, 10, 11, 2)
* delete: delete 3, 6, 11, 1 in list (-> 4, 4, 2, 10, 2)
* insert: insert 16 in 4th position of list (-> 4, 4, 2, 16, 10, 2)
* insert: insert 20 after 10 in list (-> 4, 4, 2, 16, 10, 20, 2)
* find: find max element in list (-> 20)
* sort: sort list in asce order (-> 2, 2, 4, 4, 10, 16, 20)
*
* task2:
* create: create list2 which data is 2, 3, 5, 1, 7, 8
* sort: sort list2 (-> 1, 2, 3, 5, 7, 8)
* merge: merge list2 to list keep asce order (-> 1, 2, 2, 2, 3, 4, 4, 5, 7, 8, 10, 16, 20)
* set: remove repeat element (-> 1, 2, 3, 4, 5, 7, 8, 10, 16, 20)
*/
首先理解指针与二级指针,如果需要修改一个指针的指向,那么需要传二级指针,如果只修改指针指向地址的内容,则一级指针就可以。
- 首先定义单链表
typedef int T;
typedef struct ListNode
{
T data;
struct ListNode* next;
} List;
- 创建单链表
如果分配一整块空间给单链表,释放的时候free一个指针就会把整个空间释放掉,不方便节点操作,因此一个一个节点创建:void create_list(List** list_p, T data[], int N){ List* nex = malloc(sizeof(List)); nex->data = data[N-1]; nex->next = NULL; List* cur; for(int i = N-2; i >=0; i--){ cur = malloc(sizeof(List)); cur->data = data[i]; cur->next = nex; nex = cur; } *list_p = cur; }
- 打印单链表
void print_list(List* list){ while(list != NULL){ printf("%d, ", list->data); list = list->next; } printf("\n"); }
- 在头部增加一个元素
void add_element(List **list_p, T data){ List* list = *list_p; List* new_node = malloc(sizeof(List)); // create a new node new_node->data = data; new_node->next = list; *list_p = new_node; }
- 删除一个元素
void delete_element(List **list_p, T data){ List* cur = *list_p; List* pre; //find a new head while(cur && cur->data == data){ pre = cur; cur = cur->next; free(pre); } *list_p = cur; pre = cur; cur = cur->next; while(cur != NULL){ // ->x->x-> ... ->null if(cur->data == data){ pre->next = cur->next; cur->next = NULL; free(cur); cur = pre->next; } else{ pre = cur; cur = cur->next; } } }
- 测试
int main(){
T data1[] = {1, 4, 6, 2, 10, 11, 2};
List* list;
T n = 7;
create_list(&list, data1, n);
print_list(list);
add_element(&list, 1);
add_element(&list, 4);
add_element(&list, 3);
print_list(list);
delete_element(&list, 3);
print_list(list);
delete_element(&list, 6);
print_list(list);
delete_element(&list, 11);
print_list(list);
delete_element(&list, 1);
print_list(list);
delete_element(&list, 0);
print_list(list);
return 0;
}
7. 在指定位置插入元素
int insert_position(List** list_p, T data, T position){
List* list = *list_p;
if(position == 1){ // insert in head
add_element(list_p, data);
return 1;
}
for(int i=1; i<position-1; i++){
if(!(list))
return 0;
list = list->next;
}
// if list elements num < position-1
if(!list)
return 0;
List* new_node = malloc(sizeof(List));
new_node->data = data;
new_node->next = list->next;
list->next = new_node;
return 1;
}
- 在某一个元素后面插入一个新元素
int insert_after_element(List* list_p, T data, T after_element){
while(list_p){
if(list_p->data != after_element)
list_p = list_p->next;
else break;
}
if(!list_p)
return 0;
List* new_node = malloc(sizeof(List));
new_node->data = data;
/* in single way link list, insert to tail is the same as insert to middle
if(list_p->next){
new_node->next = list_p->next;
list_p->next = new_node;
}else{ // insert in tail
list_p->next = new_node;
new_node->next = NULL;
}
*/
new_node->next = list_p->next;
list_p->next = new_node;
return 1;
}
- 找到某一个元素
List* find_max(List* list){
List* max = list;
while(list->next){
list = list->next;
if(list->data > max->data)
max = list;
}
return max;
}
- 对单链表升序排序
void sort_in_asce(List** list_p){
List* cur = *list_p;
List *min, *head, *head_pre, *min_pre;
int len=0;
while(cur){
cur = cur->next;
len++;
}
head_pre = NULL;
min_pre = NULL;
head = *list_p;
for(int i=0;i<len-1; i++){
// find min element
min = head;
cur = head;
while(cur->next){
if(min->data > cur->next->data){
min_pre = cur;
min = cur->next;
}
cur = cur->next;
}
// insert min between head_pre and head
if(min != head){
if(head == *list_p){ // insert in head
min_pre->next = min->next;
min->next = head;
*list_p = min;
}else{
min_pre->next = min->next;
head_pre->next = min;
min->next = head;
}
head_pre = min;
}else{
head_pre = min;
head = head->next;
}
}
}
- 合并两个链表并升序排序
void merge_2_list(List** list1_p, List** list2_p){
sort_in_asce(list2_p);
List* list1 = *list1_p;
List* list2 = *list2_p;
List *merge;
List* merge_head = malloc(sizeof(List));
merge_head->data = 0;
merge_head->next = NULL;
merge = merge_head;
while(list1 && list2){
if(list1->data < list2->data){
merge->next = list1; merge = merge->next;
list1 = list1->next;
}else{
merge->next = list2;
merge = merge->next;
list2 = list2->next;
}
}
if(list1)
merge->next = list1;
if(list2)
merge->next = list2;
*list1_p = merge_head->next;
merge_head->next = NULL;
free(merge_head);
}
- 删除重复元素
void remove_repeat_element(List* list){
List *pre, *cur;
List *tmp;
pre = list;
cur = list->next;
while(cur){
if(cur->data == pre->data){
tmp = cur;
pre->next = cur->next;
cur = cur->next;
free(tmp);
}else{
pre = cur;
cur = cur->next;
}
}
}
- 测试
int main(){
T data1[] = {1, 4, 6, 2, 10, 11, 2};
List* list;
T n = 7;
create_list(&list, data1, n);
print_list(list);
//add by hng
add_element(&list, 1);
add_element(&list, 4);
add_element(&list, 3);
print_list(list);
delete_element(&list, 3);
print_list(list);
delete_element(&list, 6);
print_list(list);
delete_element(&list, 11);
print_list(list);
delete_element(&list, 1);
print_list(list);
delete_element(&list, 0);
print_list(list);
printf("\n");
if(insert_position(&list, 16, 4))
print_list(list);
else
printf("insert position false\n");
printf("\n");
if(insert_after_element(list, 20, 10))
print_list(list);
else
printf("insert atfer elemnt false\n");
List* max = find_max(list);
printf("max element in list is %d\n",max->data);
sort_in_asce(&list);
print_list(list);
T data2[] = {2, 3, 5, 1, 7, 8};
List* list2;
n = 6;
create_list(&list2, data2, n);
printf("list2: \n");
print_list(list2);
sort_in_asce(&list2);
print_list(list2);
merge_2_list(&list, list2);
print_list(list);
remove_repeat_element(list);
print_list(list);